如何使用Doctrine MongoDB中的QueryBuilderAPI为一个字段的多个条件查找文档?

时间:2011-04-17 12:45:44

标签: mongodb doctrine symfony query-builder

我在MongoDB中有一个数据模型,我可以通过本机MongoDB查询成功查询。但是,我无法使用Doctrine MongoDB ODM的Query Builder API表达它们。

这是我的模型在MongoDB中的样子(这是一些JSON代码示例):

{ "name": "ArticleName", 
  "features": {
    { "type": "color",
      ...
      "values": {
        { "value": "RED", 
          "label": "red",
          ....
        },

        { "value": "GREEN", 
          "label": "green" }
      } 
    },
    { "type": "width",
      "values": {
        { "value": "40"}
      } 
    }
  }
}

我希望通过搜索不同的特征值组合来查找文章,例如我想找一篇color = green和width = 40的文章。

但是,我无法使用Doctrine MongoDB ODM Query Builder API构建查询**?这就是我试过的:

# Document/ArticleRepository.php    

$features = array('color'=>'RED', 'width'=>'40');
$qb = $this->createQueryBuilder('CatalogBundle:Article'); // I use symfony 2
foreach ($features as $type => $value)
{
    $qb->field('features')->elemMatch(
        $qb->expr()->field('type')->equals($type)->field('values')->elemMatch(
            $qb->expr()->field('value')->equals($value)
        )
    );
}
return $qb->getQuery()->execute();

但是这会导致查询,其中只包含一个条件。另一个条件似乎被覆盖了。这是查询生成器生成的查询

db.articles.find({ "features": { "$elemMatch": { "type": "width", "values": { "$elemMatch": { "value": 40 } } } } })

有没有办法用MongoDB ODM Query Builder API解决我的用例?

1 个答案:

答案 0 :(得分:5)

我同时使用 $ all-Operator 解决了我的问题。我构建了一个表达式数组,它们被传递给Doctrine MongoDB all() - Method。我在上面尝试的$elemMatch策略甚至不能用于MongoDB。您必须在末尾添加 - > getQuery()才能将表达式写入数组。由于某些原因表达式尚未记录,但您可以在 source code 中查看其功能。

# Document/ArticleRepository.php

$features = array('color'=>'RED', 'width'=>'40');
$qb = $this->createQueryBuilder('CatalogBundle:Article');
$all_features[] = array();

foreach ($features as $templateID => $value)
{
    # Add expression as a subquery to array
    $all_features[] = $qb->expr()->elemMatch(
        $qb->expr()->field('templateID')->equals($templateID)->field('values')->elemMatch(
            $qb->expr()->field('value')->equals($value)
        )
    )->getQuery();
}
# Add expressions to query
$qb->field('features')->all($all_features);

表达式支持构建查询时可以使用的几乎所有方法。您可以通过隔行几个表达式来构建MongoDB请求。这允许您构建复杂的MongoDB查询,否则只能通过将数组传递给findBy() - 方法来构建。但是,对于Doctrine ODM的当前版本(Beta 2),此策略不允许您向MongoDB链添加更多方法,例如.limit()

所以表达式看起来是使用Doctrine MongoDB构建复杂查询的最佳策略。