我有一个通过多对多关联连接到 Tag
的 Webinar
实体。
我想通过标签列表获取网络研讨会,因此网络研讨会必须具有列表中的所有标签才能出现在结果中。
我有以下代码来查询它:
$tags = [1, 2];
// Base query.
$builder = $this->getEntityManager()->createQueryBuilder()
->select('W, VR, AR, T')
->from('Model:Webinar', 'W')
->leftJoin('W.videoRecord', 'VR')
->leftJoin('W.audioRecord', 'AR')
->leftJoin('W.tags', 'T')
;
// Tags query.
if (isset($tags)) {
$builder
->andWhere('T.id IN (:tags)')
->setParameter('tags', $tags)
;
}
// Other conditions.
// ...
// Issuing the query.
return $builder->getQuery()->getResult();
此查询将为我提供列表中至少有一个标签 (OR) 的所有网络研讨会,但我希望它包含列表中的所有标签 (AND)。
我找到了这个answer 。但看起来我有一个更复杂的示例,我不确定如何重写我的代码以实现正确的行为,我有其他连接的实体和附加条件。是否可以在不破坏整个查询和其他条件的情况下将此行为隔离在单个 block 中?
最佳答案
我无法在单个查询中同时使用聚合和获取,因此我决定将其分成两部分。
通过使用第一个查询,我将应用所有必要的条件来接收网络研讨会 ID 列表,并通过使用第二个查询,我将获取这些 ID 的对象图。
这是完整的示例:
// I. Making the first query to fetch only webinar IDs.
// Base query.
$builder = $this->getEntityManager()->createQueryBuilder()
->select('W.id')
->from('Model:Webinar', 'W')
->orderBy('W.' . $sort, $order)
;
// Selected tags condition.
if (is_array($criteria['tags']) && count($criteria['tags']) > 0) {
$builder
->innerJoin('W.tags', 'T', 'WITH', 'T.id IN (:tags)')
->setParameter('tags', $criteria['tags'])
->groupBy('W.id')
->having('COUNT(T.id) = :tags_count')
->setParameter('tags_count', count($criteria['tags']))
;
}
// Any additional conditions
// ...
// Building the list of webinar IDs.
$ids = [];
foreach ($builder->getQuery()->getScalarResult() as $record) {
$ids[] = $record['id'];
}
// II. And now selecting complete object graph for specified webinar IDs.
// Base query.
$builder = $this->getEntityManager()->createQueryBuilder()
->select('W, VR, AR, T')
->from('Model:Webinar', 'W')
->leftJoin('W.videoRecord', 'VR')
->leftJoin('W.audioRecord', 'AR')
->leftJoin('W.tags', 'T')
->where('W.id IN (:ids)')
->setParameter('ids', $ids)
;
// Issuing the query.
return $builder->getQuery()->getResult();
我希望它能对某人有所帮助。干杯!
关于symfony - Doctrine ORM 通过标签列表选择文章,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23999545/