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

发布于 2024-11-02 01:54:47 字数 1455 浏览 7 评论 0原文

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

这就是我的模型在 MongoDB 中的外观(这是一些 JSON 代码示例):

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

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

我想通过搜索不同的特征值组合来查找文章,例如我想查找一篇颜色=绿色且宽度=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 查询生成器 API 解决我的用例吗?

I have a data model in MongoDB which I can successfully query by native MongoDB queries. However I'm not able to express them with the Query Builder API of Doctrine MongoDB ODM.

This is how my model looks in MongoDB (this is some example JSON-Code):

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

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

I want to find articles by searching for different feature-value combinations, e.g. I want to find an article with color=green and width=40.

However, I was not able to build a query for that with the Doctrine MongoDB ODM Query Builder API**? This is what I tried:

# 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();

However this does result into a query, which contains only one condition. The other condition seems to be overwritten. This is the query generated by the Query Builder:

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

Is there a way to solve my use case with the MongoDB ODM Query Builder API?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对风讲故事 2024-11-09 01:54:47

同时我通过使用 $all-Operator 解决了我的问题。我构建了一个表达式数组,将其传递给 Doctrine MongoDB all()-方法。我上面尝试过的 $elemMatch 策略甚至不适用于 MongoDB。您必须在末尾添加 ->getQuery() 才能将表达式写入数组。由于某些原因表达式尚未记录,但是您可以在源代码

# 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 构建复杂查询的最佳策略。

I meanwhile solved my problem by using the $all-Operator. I build an array of Expressions, which are passed to the Doctrine MongoDB all()-Method. The strategy with $elemMatch I tried above would not even have worked with MongoDB. You have to add ->getQuery() at end to be able to write the expression to an array. For some reason expressions are not yet documented, however you can check their functionality in the 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);

An expression supports pretty much all methods you can use when building a query. You can build your MongoDB request by interlacing several expressions. This allows you to build complex MongoDB Queries you could build otherwise only by passing an array to the findBy()-Method. However with the current version (Beta 2) of the Doctrine ODM this strategy would not allow you to add more methods to the MongoDB chain, like .limit().

So expressions look like the best strategy to build complex queries with Doctrine MongoDB.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文