MongoDB无法匹配聚合返回的对象字段
我无法通过从另一个集合聚合的对象的字段筛选查找结果 我有以下聚合函数:MongoDB无法匹配聚合返回的对象字段,mongodb,aggregation-framework,match,lookup,Mongodb,Aggregation Framework,Match,Lookup,我无法通过从另一个集合聚合的对象的字段筛选查找结果 我有以下聚合函数: db.Persons.aggregate([ { $lookup: { from: "Addresses", localField: "addressId", foreignField: "_id", as: "address" } }, { $unwind: "$address" } ]) 返回类似于: { "_id" : "5dfa9", "addressId" :
db.Persons.aggregate([
{ $lookup:
{
from: "Addresses",
localField: "addressId",
foreignField: "_id",
as: "address"
}
},
{ $unwind: "$address" }
])
返回类似于:
{
"_id" : "5dfa9",
"addressId" : ObjectId("5df95bd35a65a59142faa6be"),
"text" : "abc",
"address" :
{
"_id" : ObjectId("5df95bd35a65a59142faa6be"),
"townId" : "3"
}
}
添加$match
时:
db.Persons.aggregate([
{ $match: { address: { $elemMatch: { "townId": "3" } } } },
{ $lookup: { ... } },
{ $unwind: "$address" }
])
我什么也得不到。但是,添加这样的匹配项{$match:{text:“abc”}
非常有效
EDIT:正如@Adam Harrison在评论中所建议的那样,需要在$lookup
语句之后添加$match
语句,以使其正常工作。另外,{$unwind:$address}
需要删除
db.Persons.aggregate([
{ $lookup: { ... } },
{ $match: { address: { $elemMatch: { "townId": "3" } } } }
])
简单回答
如果要对
$lookup
的结果进行筛选,则需要将$match
阶段放置在管道中的$lookup之后。Persons集合似乎没有address.townId
字段,这意味着$match
返回零个文档
更好的答案
也就是说,您可能希望在地址
集合上启动此操作,并对人员执行$lookup
,而不是相反的方式
聚合框架操作可以利用索引。当前管道以$lookup
开始,因此它将对Persons
集合执行完整的集合扫描,其中它可能会扫描大量不必要的文档,效率非常低
在地址
上启动聚合将允许您在管道的开头放置一个可索引的$match
阶段,并有助于避免扫描不必要的人员
文档:
db.Addresses.aggregate([
{ "$match" : { "townId" : 3 } }, // Can use index { townId: 1 } on Addresses
{ "$lookup": { "from" : "Persons", "localField" : "_id", "foreignField" : "addressId", "as" : "Persons" } },
{ "$unwind" : "$Persons" },
...
])
此聚合现在通过<代码>地址> <代码>有效地查询<代码>人>代码>集合,因此您应该考虑在<代码>人>代码>下建立<代码> {地址:1 } <代码>索引。p> 似乎
$match
是您的初始阶段吗?那么就不需要查看$lookup
的结果,因为问题应该在查找之前出现,您能否更新此问题以提供两个集合中具有预期结果的示例文档..如何{$match:{“FOOBAR.townId”:“3”}
?如果要对$lookup
的结果进行筛选,则需要将$match
阶段放置在管道中的$lookup
之后。看起来Persons
集合没有address.townId
字段,这意味着$match
返回零个文档。有意义吗?当然,这是最明显的一个!我想我已经试过了几乎所有的方法。我只需要删除{$unwind:“$address”}
,它就可以正常工作了。谢谢P.S.@AdamHarrison也许你可以在下面添加答案,这样我就可以接受了?谢谢你的补充!我一定会记住这一点。