Doctrine 2 manyToMany关系用AND选择实体

时间:2014-02-18 14:03:44

标签: symfony doctrine-orm many-to-many entities

我正在建立一个网站,需要能够根据他们的选项过滤别墅。例如:别墅有多种选择:Wi-Fi,游泳池,动物允许。

过滤时,我会提供以下选项:Wi-Fi和Pool。我现在需要一个基于这些选项的过滤别墅列表。所以我只想要拥有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)

任何人都可以对此有所了解吗?

1 个答案:

答案 0 :(得分: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));
}