Symfony 根据标签列表选择文章

Symfony 根据标签列表选择文章,symfony,doctrine-orm,tags,many-to-many,dql,Symfony,Doctrine Orm,Tags,Many To Many,Dql,我有一个网络研讨会实体,它连接到具有多对多关联的标签 我想通过标签列表获取网络研讨会,因此网络研讨会必须具有列表中的所有标签才能显示在结果中 我有以下代码来查询它: $tags=[1,2]; //基本查询。 $builder=$this->getEntityManager()->createQueryBuilder() ->选择('W、VR、AR、T') ->from('Model:Webinar','W') ->leftJoin('W.videoRecord','VR') ->leftJoin

我有一个
网络研讨会
实体,它连接到具有多对多关联的
标签

我想通过标签列表获取网络研讨会,因此网络研讨会必须具有列表中的所有标签才能显示在结果中

我有以下代码来查询它:

$tags=[1,2];
//基本查询。
$builder=$this->getEntityManager()->createQueryBuilder()
->选择('W、VR、AR、T')
->from('Model:Webinar','W')
->leftJoin('W.videoRecord','VR')
->leftJoin('W.audioRecord','AR')
->leftJoin('W.tags','T')
;
//标签查询。
如果(isset($tags)){
$builder
->andWhere('T.id IN(:tags)'))
->setParameter('tags',$tags)
;
}
//其他条件。
// ...
//发出查询。
返回$builder->getQuery()->getResult();
此查询将为我提供列表中至少有一个标记(或)的所有网络研讨会,但我希望它在列表中有所有标记(和)


我找到了这个。但看起来我有一个更复杂的例子,我不确定如何重新编写代码以启用正确的行为,我有其他连接的实体和附加条件。是否可以在单个块中隔离此行为,而不破坏整个查询和其他条件?

这就是sql的
in
子句的工作方式,它接受
列表中
项的所有
行。您必须执行类似于您提供的答案的操作,因此在您的情况下,您的查询如下所示:

// 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)
    ;


    $builder->groupBy('T.id')
        ->having("COUNT(DISTINCT T.id) = :count")
        ->setParameter("count", count($tags));
}

这应该可以正常工作,我想这就是sql在
子句中的
的工作方式,它将使用
列表中
项的所有行。您必须执行类似于您提供的答案的操作,因此在您的情况下,您的查询如下所示:

// 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)
    ;


    $builder->groupBy('T.id')
        ->having("COUNT(DISTINCT T.id) = :count")
        ->setParameter("count", count($tags));
}

这应该可以正常工作,我想我不能在一个查询中同时使用聚合和获取,所以我决定将它分成两部分

通过使用第一个查询,我将应用所有必要的条件以接收网络研讨会ID列表,通过使用第二个查询,我将获取这些ID的对象图

以下是完整的示例:

//I.进行第一次查询以仅获取网络研讨会ID。
//基本查询。
$builder=$this->getEntityManager()->createQueryBuilder()
->选择('W.id')
->from('Model:Webinar','W')
->orderBy('W..$sort,$order)
;
//选定的标签条件。
if(is_数组($criteria['tags'])和计数($criteria['tags'])>0){
$builder
->innerJoin('W.tags','T','WITH','T.id IN(:tags)'
->setParameter('tags',$criteria['tags']))
->groupBy('W.id')
->有('COUNT(T.id)=:tags\u COUNT')
->setParameter('tags_count',count($criteria['tags']))
;
}
//任何附加条件
// ...
//构建网络研讨会ID列表。
$ids=[];
foreach($builder->getQuery()->getScalarResult()作为$record){
$ids[]=$record['id'];
}
//二,。现在为指定的网络研讨会ID选择完整的对象图。
//基本查询。
$builder=$this->getEntityManager()->createQueryBuilder()
->选择('W、VR、AR、T')
->from('Model:Webinar','W')
->leftJoin('W.videoRecord','VR')
->leftJoin('W.audioRecord','AR')
->leftJoin('W.tags','T')
->其中('W.id IN(:id'))
->setParameter('ids',$ids)
;
//发出查询。
返回$builder->getQuery()->getResult();

我希望它能帮助别人。干杯

我无法在一个查询中同时使用聚合和抓取,所以我决定将它一分为二

通过使用第一个查询,我将应用所有必要的条件以接收网络研讨会ID列表,通过使用第二个查询,我将获取这些ID的对象图

以下是完整的示例:

//I.进行第一次查询以仅获取网络研讨会ID。
//基本查询。
$builder=$this->getEntityManager()->createQueryBuilder()
->选择('W.id')
->from('Model:Webinar','W')
->orderBy('W..$sort,$order)
;
//选定的标签条件。
if(is_数组($criteria['tags'])和计数($criteria['tags'])>0){
$builder
->innerJoin('W.tags','T','WITH','T.id IN(:tags)'
->setParameter('tags',$criteria['tags']))
->groupBy('W.id')
->有('COUNT(T.id)=:tags\u COUNT')
->setParameter('tags_count',count($criteria['tags']))
;
}
//任何附加条件
// ...
//构建网络研讨会ID列表。
$ids=[];
foreach($builder->getQuery()->getScalarResult()作为$record){
$ids[]=$record['id'];
}
//二,。现在为指定的网络研讨会ID选择完整的对象图。
//基本查询。
$builder=$this->getEntityManager()->createQueryBuilder()
->选择('W、VR、AR、T')
->from('Model:Webinar','W')
->leftJoin('W.videoRecord','VR')
->leftJoin('W.audioRecord','AR')
->leftJoin('W.tags','T')
->其中('W.id IN(:id'))
->setParameter('ids',$ids)
;
//发出查询。
返回$builder->getQuery()->getResult();

我希望它能帮助别人。干杯

谢谢你的建议,托马斯!我也尝试过类似的方法,但遇到以下异常:
错误:列“w0_uu.id”必须出现在GROUP BY子句中,或用于聚合函数
。感谢您给我的建议!我尝试过类似的操作,但得到了以下异常:
错误:列“w0_uw0.id”必须出现在GROUP BY子句中,或在聚合函数中使用。