如何在Doctrine Criteria中结合andWhere与orWhere构建复杂查询
使用Doctrine Criteria构建带固定条件与可选OR条件的灵活查询
看起来你已经有了核心思路,我帮你把代码补全并把逻辑梳理清楚,完美实现「固定筛选最近55天+动态添加OR条件」的需求:
完整可运行代码
use Doctrine\Common\Collections\Criteria; // 计算最近55天的时间阈值(这里用DateTime对象更贴合Doctrine的字段类型,也可以用时间戳) $dateThreshold = (new \DateTime())->modify('-55 days'); $criteria = Criteria::create(); // 固定必加的条件:筛选最近55天创建的游戏 $criteria->where(Criteria::expr()->gte('gameCreation', $dateThreshold)); // 用来收集所有可选OR条件的数组 $orConditions = []; // 第一个可选条件:根据英雄ID列表添加OR筛选 if (!empty($champions)) { foreach ($champions as $championId) { $orConditions[] = Criteria::expr()->eq('championId', $championId); } } // 第二个可选条件:示例扩展——根据游戏模式添加OR筛选(你可以根据实际需求增减) if (!empty($gameModes)) { foreach ($gameModes as $mode) { $orConditions[] = Criteria::expr()->eq('gameMode', $mode); } } // 如果有收集到可选OR条件,就把它们组合后加入查询 if (!empty($orConditions)) { // 用orX把所有OR条件打包成一组,再通过andWhere加入主查询 // 最终逻辑:(最近55天) AND (英雄1 OR 英雄2 OR ... OR 模式1 OR 模式2 OR ...) $criteria->andWhere(Criteria::expr()->orX(...$orConditions)); } // 最后用这个Criteria去查询你的集合,比如: // $filteredGames = $gameCollection->matching($criteria);
核心逻辑说明
- 固定条件的优先级:先用
where()设置的最近55天筛选是最外层的AND条件,确保所有返回结果都必须满足这个时间要求,不会被后续的OR条件覆盖。 - OR条件的灵活扩展:你可以无限添加新的可选参数判断(比如段位、胜负状态等),只要把对应的条件表达式推入
$orConditions数组即可,核心查询逻辑不需要改动。 - 字段类型适配:如果你的
gameCreation字段是DateTime类型,直接传入DateTime对象比时间戳更稳妥,Doctrine会自动处理数据库层面的类型转换。
内容的提问来源于stack exchange,提问作者PrimuS
相关产品推荐
相关产品推荐

