我在使用PHP中的MongoDB ODM查询构建器返回匹配的嵌入式文档时遇到了麻烦。每个嵌入的文档都有一个创建时生成的MongoID。以下是我的文档结构项目:
{
"_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"
}
]
}
现在我想从数据库中只检索符合我的标准的类嵌入式文档中的类(即类具有特定的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"
}
]
}
但是,学说正在返回整个项目记录(显示在问题的开头)。我也尝试使用$match聚合构建聚合查询,结果仍然与查询相同使用聚合构建器创建的内容如下:
$qb = $dm->createAggregationBuilder('Documents\Project');
$projectObj = $qb
->match()
->field('id')->equals($projectId)
->field('classes._id')->equals(new \MongoId($classId))
->execute()
->getSingleResult();
有人可以帮我解决这个问题吗?如何构建我得到所需结果的查询,如上所述。
答案 0 :(得分:0)
因此,在遇到麻烦之后,我只能使用聚合构建器检索匹配的嵌入式文档。所以感谢@ 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
过滤嵌入的文档。希望这将有助于未来有同样问题的人。