如何在api-platform查询字符串中添加group by实现数据去重
API Platform实现groupBy查询参数去重方案
实现思路:通过API Platform的Doctrine ORM查询扩展,自定义解析请求中的groupBy参数,动态添加到查询构造器中实现分组去重。
步骤1:创建GroupBy查询扩展类
在项目src/Doctrine目录下新建GroupByExtension.php文件,代码如下:
<?php namespace App\Doctrine; use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface; use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; use ApiPlatform\Metadata\Operation; use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpFoundation\RequestStack; class GroupByExtension implements QueryCollectionExtensionInterface { public function __construct(private RequestStack $requestStack) { } public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void { $request = $this->requestStack->getCurrentRequest(); if (null === $request || !$request->query->has('groupBy')) { return; } $groupByField = $request->query->get('groupBy'); // 字段白名单验证,避免SQL注入风险,可根据实际资源调整允许分组的字段 $allowedFields = ['Name']; if (!in_array($groupByField, $allowedFields)) { return; } $rootAlias = $queryBuilder->getRootAliases()[0]; $queryBuilder->groupBy(sprintf('%s.%s', $rootAlias, $groupByField)); } }
步骤2:注册扩展服务
如果你的项目未开启服务自动装配,需要在config/services.yaml中添加如下配置:
services: App\Doctrine\GroupByExtension: tags: - { name: api_platform.doctrine.orm.query_extension.collection }
步骤3:效果验证
请求地址 www.mySite.com/api/MyEntity.json?groupBy=Name 即可获取按Name字段分组去重后的结果。
注意事项
- 若需要同时返回count、sum等聚合计算结果,可在扩展中补充
select部分的逻辑,自定义返回字段规则 - 必须保留字段白名单校验逻辑,禁止用户传入任意字段作为分组依据,避免SQL注入安全风险
- 如果你使用的是3.0以下版本的API Platform,需要将扩展实现的接口命名空间调整为
ApiPlatform\Core\Doctrine\Orm\Extension\QueryCollectionExtensionInterface
内容的提问来源于stack exchange,提问作者user17417092
相关产品推荐
相关产品推荐

