【问题标题】:Doctrine MongoDB ODM - Return only matched embedded document using query builderDoctrine MongoDB ODM - 使用查询生成器仅返回匹配的嵌入式文档
【发布时间】:2017-11-01 16:29:50
【问题描述】:

我在 PHP 中使用 MongoDB ODM 查询构建器仅返回匹配的嵌入文档时遇到了问题。每个嵌入文档都有一个在创建时生成的 MongoID。以下是我收集 Project 的文档结构:

{ 
    "_id" : ObjectId("59f889e46803fa3713454b5d"), 
    "projectName" : "usecase-updated", 
    "classes" : [
        {
            "_id" : ObjectId("59f9d7776803faea30b895dd"), 
            "className" : "OLA"
        }, 
        {
            "_id" : ObjectId("59f9d8ad6803fa4012b895df"), 
            "className" : "HELP"
        }, 
        {
            "_id" : ObjectId("59f9d9086803fa4112b895de"), 
            "className" : "DOC"
        }, 
        {
            "_id" : ObjectId("59f9d9186803fa4212b895de"), 
            "className" : "INVOC"
        }
    ]
}

现在我想从数据库中只检索 classes 符合我的标准 的嵌入文档中的 class(即 class具有特定 ID)。这就是我构建查询的方式:

$qb = $dm->createQueryBuilder('Documents\Project');
$projectObj = $qb
    ->field('id')->equals("59f889e46803fa3713454b5d")
    ->field('classes')->elemMatch(
        $qb->expr()->field("id")->equals(new \MongoId("59f9d7776803faea30b895dd"))
    )
    ->hydrate(false)
    ->getQuery()
    ->getSingleResult();

首先我匹配项目 ID,然后匹配嵌入文档类 ID。我希望它只返回 OLA 的嵌入文档,如下所示:

{ 
   "_id" : ObjectId("59f889e46803fa3713454b5d"), 
    "projectName" : "usecase-updated", 
    "classes" : [
          {
            "_id" : ObjectId("59f9d7776803faea30b895dd"), 
            "className" : "OLA"
          }
     ]
}

但是教义正在返回整个 Project 记录(显示在问题的开头)。我还尝试使用 $match 聚合构建聚合查询,结果仍然与我创建的查询相同聚合生成器如下:

$qb = $dm->createAggregationBuilder('Documents\Project');
    $projectObj = $qb
        ->match()
        ->field('id')->equals($projectId)
        ->field('classes._id')->equals(new \MongoId($classId))
        ->execute()
        ->getSingleResult();

有人可以帮我解决这个问题吗?如上所述,我如何构建获得所需结果的查询。

【问题讨论】:

  • ODM 可以处理整个文档。要么在应用中过滤它,要么使用aggregation
  • @AlexBlex 我也尝试过,但结果仍然相同。我用聚合查询生成器更新了问题
  • 您正在使用单个 match 阶段,它与 find 完全一样。之后,您至少需要一个 project 阶段来重新塑造文档。看看那里的array functions

标签: php mongodb doctrine doctrine-odm doctrine-query


【解决方案1】:

因此,在遇到一些麻烦之后,我只能使用聚合构建器检索匹配的嵌入文档。所以感谢@Alex Bles 的评论,我能够更多地考虑使用聚合函数,我找到了$filter 数组聚合函数并尝试使用它构建查询,最终查询是这样的:

    $qb = $dm->createAggregationBuilder('Documents\Project');
    $classObject = $qb->match()
       ->field("id", new \MongoId($projectId))
       ->project()
       ->field("classes")
       ->filter('$classes', 'class', $qb->expr()->eq('$$class._id', new \MongoId($classId)))
       ->execute()->getSingleResult();

所以在查询中我首先匹配了项目的_id。然后在该项目中,我使用$filter 数组聚合方法预测了classes 的结果。最后,我能够获得由他们的_id 过滤的嵌入文档。希望这对以后遇到同样问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 2012-01-16
    • 2012-12-20
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多