- Published on
Api platform 教程10---过滤
原创文章,转载时需取得本人同意并注明来源
- Authors
-
-
- Name
- langziyang
-
Api platform 教程10---过滤
现在我们基本能做一个CRUD了,一点问题都没有,但是客户现要要求在长达几千条数据中按条件过滤一些数据,很简单,Api platform 附带了一系列内置过滤器,允许您按文本、布尔值、日期等过滤结果集合。
它的工作原理如下:在类上方添加一个名为 ApiFilter 的属性。
通常,我们需要两个参数,第一个是过滤器类,然后是过滤字段名
假设我们想按Treasure的name字段过滤,这是一个string,所以我们用SearchFilter:
#[ApiFilter(SearchFilter::class, properties: ['name' => 'partial'])]
#[ApiFilter(BooleanFilter::class, properties: ['isPublished'])]
#[ApiFilter(DateFilter::class, properties: ['createdAt'])]
#[ApiFilter(RangeFilter::class, properties: ['value'])]
class DragonTreasure
{
//...
}
properties我们开启了name字段,搜索支持exact, partial, start, end和word_start匹配策略。
- partial 策略使用 LIKE %text% 搜索包含 text 的字段。
- start 策略使用 LIKE text% 搜索以 text 开头的字段。
- end 策略使用 LIKE %text 搜索以 text 结尾的字段。
- word_start 策略使用 LIKE text% OR LIKE % text% 搜索包含以 text 开头的单词的字段。
如果您希望过滤器不区分大小写,请在过滤器前面添加字母 i 。例如 ipartial 或 iexact 。请注意,这将使用 LOWER 函数,如果没有正确的索引,将会影响性能。
除了SearchFilter,我还有开启了其它几种搜索,具体怎么用,有哪些参数,请查看文档。
这里还有一个问题:多表联查,如果你想取某个用户的宝藏,你还可以通过下面的方式:
#[ApiFilter(SearchFilter::class, properties: ['name' => 'partial','user.id'=>'exact','user.email'=>'partial'])]
这样就可以通过用户的id和email来搜索了。但是如果我们的搜索并不在Entity字段中又怎么办呢?
我们还可以extending api platform:
#src/ApiResource/Extensions/DragonTreasureCollectionExtension.php
<?php
namespace App\ApiResource\Extensions;
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\CollectionOperationInterface;
use ApiPlatform\Metadata\Operation;
use App\Entity\DragonTreasure;
use Doctrine\ORM\QueryBuilder;
class DragonTreasureCollectionExtension implements QueryCollectionExtensionInterface
{
public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
{
if ($resourceClass !== DragonTreasure::class || !$operation instanceof CollectionOperationInterface) {
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder->andWhere(sprintf('%s.coolFactor=:coolFactor', $rootAlias))
->setParameter('coolFactor', 1);
}
}
上面的代码添加了一个简单的查询条件,我相信你稍微看一看就能明白