Symfony Doctrine 一对多和 X 查询生成器

Symfony Doctrine One to Many andX query builder

我有一个具有 OneToMany AttributeValues 的 Product 实体。每个 AttributeValue 都有一个属性关系和一个“值”参数。

我想过滤同时具有“颜色”(属性)“黑色”(值)和“尺寸”“2m”的产品。

        $qb->leftJoin("product.attrVal","attrVal");
        $andX = $qb->expr()->andX();
        $count = 0;
        foreach($params['filters'] as $att_id => $values) {
            foreach ($values as $val){
                $andX->add("attrVal.attribute = :att_id_".$count." and attrVal.value = :val_".$count);
                $qb->setParameter("att_id_".$count, $att_id);
                $qb->setParameter("val_".$count, $val);
                $count++;
            }

        }
        $qb->andWhere($andX);
    

当然,这只有在只给出一个属性的情况下才有效。如果过滤器数组包含多个值,则不会给出任何结果。可能是因为它希望满足同一 AttributeValue 对象的所有条件,而不是寻找满足至少一个条件的所有 AttributeValue 对象。但我的最终目标是一次找到具有所有给定属性的对象。但无法弄清楚如何在查询构建器中说明这一点。

谢谢!

我找到了解决办法。也许它不是最好的,但它确实有效。

我首先 innerJoining 我的属性并计算它们。

    $qb->from($this->_entityName, 'product')    
    $qb->addSelect('product')    
    $qb->innerJoin("product.attributes","attributes");
    $qb->addSelect('COUNT(attributes.id) AS attributesCount');
    $qb->groupBy('product.id');

然后我添加一个 orX 而不是 andX,以获得至少具有一个属性的所有产品。

    $orX = $qb->expr()->orX();
    $count = 0;
    foreach($params['filters'] as $att_id => $values) {
        foreach ($values as $val){
            $orX->add("attributes.attribute = :att_id_".$count." and attributes.value = :val_".$count);
            $qb->setParameter("att_id_".$count, $att_id);
            $qb->setParameter("val_".$count, $val);
            $count++;
        }

    }
    $qb->andWhere($orX);

最后,我确保 return 只计算所有已定义属性的值。过滤掉不具备所有属性的产品。

    $qb->having("attributesCount = :ac");
    $qb->setParameter("ac", $count);