2014-02-18 62 views
1

我正在建立一個網站,需要能夠根據他們的選擇過濾別墅的網站。舉個例子:一個別墅可以選擇: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。我不是這樣的常規海報(正如你可以通過這個非常非常晚的反應看到的那樣。所以我沒有意識到可用的選項:-)如你所說。謝謝。希望它也能幫助你。 –

回答

0

解決

還好吧,所以我想通了。我的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)); 
}