Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB无法匹配聚合返回的对象字段_Mongodb_Aggregation Framework_Match_Lookup - Fatal编程技术网

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也许你可以在下面添加答案,这样我就可以接受了?谢谢你的补充!我一定会记住这一点。