You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API Platform中按评分平均值过滤Games实体数据?

错误原因

你的HAVING子句写法不符合DQL语法要求:andHaving()方法需要传入一个返回布尔值的判断表达式,但你只写了avg('r.value')这个聚合计算结果,没有指定比较规则(比如大于等于多少分),DQL解析器在等待你输入比较符和比较值的时候,遇到了后续自动拼接的ORDER BY语句,就抛出了语法错误。

解决方案

根据你的业务需求选择对应修改方案:

方案1:筛选平均评分不低于指定阈值的游戏

比如请求/games?rate=4就返回平均评分≥4分的游戏,修改apply方法中的查询构造逻辑:

public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null, array $context = [])
{
    if (isset($context['filters']) && is_array($context['filters'])) {
        $rate = $context['filters'][$this->parameterName] ?? null;
        if (!$rate || !is_numeric($rate)) {
            return;
        }
    } else {
        return;
    }

    // 生成唯一别名避免字段冲突
    $avgRateAlias = $queryNameGenerator->generateParameterName('avg_rate');
    $thresholdParam = $queryNameGenerator->generateParameterName('rate_threshold');

    $queryBuilder
        ->join('o.rates', 'r')
        // HIDDEN关键字表示这个字段不参与结果返回,只用于查询逻辑
        ->addSelect(sprintf('AVG(r.value) AS HIDDEN %s', $avgRateAlias))
        ->groupBy('o.id')
        ->andHaving(sprintf('%s >= :%s', $avgRateAlias, $thresholdParam))
        ->setParameter($thresholdParam, $rate)
        // 可选:按平均分从高到低排序
        ->orderBy($avgRateAlias, 'DESC');
}

方案2:仅按平均评分从高到低排序返回游戏

如果参数rate只是触发排序的开关,不需要指定阈值,修改逻辑如下:

public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null, array $context = [])
{
    if (isset($context['filters']) && is_array($context['filters'])) {
        if (!isset($context['filters'][$this->parameterName])) {
            return;
        }
    } else {
        return;
    }

    $avgRateAlias = $queryNameGenerator->generateParameterName('avg_rate');
    $queryBuilder
        ->join('o.rates', 'r')
        ->addSelect(sprintf('AVG(r.value) AS HIDDEN %s', $avgRateAlias))
        ->groupBy('o.id')
        ->orderBy($avgRateAlias, 'DESC');
}

额外注意

  • 你当前请求参数传的是?rate=game,如果是要按阈值筛选,需要传数字类型的参数值,比如?rate=3.5
  • 如果需要支持筛选平均分区间,可以扩展参数格式,比如传入数组?rate[gte]=4&rate[lte]=5做对应逻辑处理即可

内容的提问来源于stack exchange,提问作者kevin73

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:15:05