学说2 manyToMany关系选择实体与AND

问题描述:

我正在建立一个网站,需要能够根据他们的选择过滤别墅的网站。举个例子:一个别墅可以选择:Wi-Fi,游泳池,动物可以。学说2 manyToMany关系选择实体与AND

当过滤我给出的选项:Wi-Fi和池。我现在需要基于这两个选项的别墅过滤列表。所以我只想要有Wi-Fi和游泳池的别墅。

我的别墅实体看起来是这样的:

class Object 
{ 
/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="name", type="string", length=255) 
*/ 
private $name; 

/** 
* @ORM\manyToMany(targetEntity="Option", mappedBy="objects") 
*/ 
private $options; 

//... 
} 

而且我的选择实体看起来是这样的:

class Option 
{ 

/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="name", type="string", length=255) 
*/ 
private $tag; 

/** 
* @ORM\manyToMany(targetEntity="Object", inversedBy="options") 
* @ORM\JoinTable(name="Object_Options") 
*/ 
private $objects; 

//... 
} 

我有过滤ID $filters与我需要过滤数组。

我似乎无法弄清楚如何做到这一点。

我现在有这个

$qb = $this->getEntityManager()->createQueryBuilder(); 
$qb->select("o")->from("Object", "o"); 

if ($filters && count($filters) > 0) { 
    $qb->innerJoin("o.options", "f"); 
    $qb->andWhere($qb->expr()->in("f.id", $filters)); 
} 

$query = $qb->getQuery(); 

但实际上做的是什么,我需要相反。这根据选项过滤别墅,但使用OR而不是AND。所以这给了我一个别墅Wi-Fi或游泳池的结果。

因此,在伪代码,我需要:

get all Objects that have every given option (and maybe more) 

任何一个可以提供一些线索这光?

+0

感谢您发布您的解决方案!顺便说一句,回答您自己的问题并将您的答案标记为已接受是完全可以的。实际上,这是将问题标记为已解决的首选方式。 –

+0

感谢这个信息Slava Formin II。我不是这样的常规海报(正如你可以通过这个非常非常晚的反应看到的那样。所以我没有意识到可用的选项:-)如你所说。谢谢。希望它也能帮助你。 –

解决

还好吧,所以我想通了。我的IN声明正处于正确的轨道,但它需要更多盐。显然,在选择了所有选项后,您需要检查过滤器的数量是否与您给出的过滤器数量相同。当我在MySQL中一步步尝试时,这实际上是有意义的。

$qb = $this->getEntityManager()->createQueryBuilder(); 
$qb->select("DISTINCT o")->from("Object", "o"); 

if ($filters && count($filters) > 0) { 
    $qb->innerJoin("o.options", 
        "f", 
        "WITH", 
        "f.id IN (:filters)")->setParameter("filters", $filters); 

    $qb->groupBy("o.id"); 

    $qb->having("COUNT(DISTINCT f.id) = :count") 
     ->setParameter("count", count($filters)); 
}