我正在建立一个网站,需要能够根据他们的选项过滤别墅。例如:别墅有多种选择: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)
任何人都可以对此有所了解吗?
答案 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));
}