Doctrine QueryBuilder:ManyToOne关系,其中多个subEntity必须匹配

时间:2017-10-25 10:52:12

标签: php mysql symfony doctrine-orm doctrine

我正在尝试进行查询,其中我有一个实体Job和一个实体JobProperty,其中1 Job可以有多个JobProperties

Query on a many-to-many relationship using Doctrine with Symfony2解释了如何根据一个实体的subEntities值检索一个实体的匹配项。从此我构建了查询:

$qb = $this->getDoctrine()->getRepository('AppBundle:Job')->createQueryBuilder('job')
->innerJoin('job.properties','property');

foreach($filters as $label => $value)
{
    $qb->andWhere('property.label = :label AND property.value = :value')
    ->setParameter('label',$label)
    ->setParameter('value',$value);
}

上面的查询在某种程度上有效,但它提供了一个属性与任何过滤器匹配的结果,并且不仅提供匹配所有过滤器的结果。我需要它只返回匹配所有过滤器的结果。

我可能不得不以不同的方式解决这个问题,但我不确定是否会实施。

1 个答案:

答案 0 :(得分:0)

您没有正确地将标签和值与最后的过滤器值进行匹配,因为查询中使用的占位符:label:value对于每个循环迭代都不是唯一的,因此生成了所有子句by循环将与最后一个标签和值匹配。

要获取每个属性与提供的过滤器匹配的作业,您可以像在doctrine查询下面那样编写。

首先,它将收集单独数组中的所有标签和值,然后使用IN()操作匹配作业属性,最后获取其属性与构建聚合所需的所有过滤器匹配的作业计算匹配结果,并且应该等于过滤器的数量

$qb =  $this->getDoctrine()
            ->getRepository('AppBundle:Job')
            ->createQueryBuilder('job')
            ->innerJoin('job.properties','p');
$labels = array();
$values = array();
foreach($filters as $label => $value)
{
    $labels[] = $label;
    $values[] = $value;
}
$qb->addSelect('COUNT(DISTINCT  p.id) AS total_properties')
   ->andWhere('p.label IN (:labels)')
   ->andWhere('p.value IN (:values)')
   ->addGroupBy('job.id')
   ->having('total_properties = '.count($filters))
   ->setParameter('labels',$labels)
   ->setParameter('values',$values)
   ->getQuery()
   ->getResult();
  

这里有另一个答案作为参考,与您的问题类似   Symfony2 - Doctrine2 QueryBuilder WHERE IN ManyToMany field