MongoDB聚合错误$ in需要一个数组

问题描述 投票:1回答:2

下面是我的文档,我想过滤所有这些邮政编码以及它们对应的res_count,它们也存在于名为data的数组中。

文档:

{ "data" : [ "10451", "10458", "10467", "10461", "10462" ] }
{ "zipcode" : "10470", "res_count" : 8 }
{ "zipcode" : "10454", "res_count" : 10 }
{ "zipcode" : "10466", "res_count" : 11 }
{ "zipcode" : "10455", "res_count" : 9 }
{ "zipcode" : "10462", "res_count" : 29 }
{ "zipcode" : "10461", "res_count" : 25 }
{ "zipcode" : "10467", "res_count" : 15 }
{ "zipcode" : "10465", "res_count" : 28 }
{ "zipcode" : "10452", "res_count" : 11 }
{ "zipcode" : "10469", "res_count" : 10 }
{ "zipcode" : "10459", "res_count" : 7 }
{ "zipcode" : "10457", "res_count" : 14 }
{ "zipcode" : "10451", "res_count" : 68 }
{ "zipcode" : "10463", "res_count" : 28 }
{ "zipcode" : "10458", "res_count" : 34 }
{ "zipcode" : "10468", "res_count" : 12 }
{ "zipcode" : "10475", "res_count" : 14 }
{ "zipcode" : "10474", "res_count" : 10 }
{ "zipcode" : "10473", "res_count" : 3 }

我尝试使用$in,但它说"errmsg" : "$in needs an array"

mongodb mongodb-query aggregation-framework
2个回答
0
投票

尝试一下:

  db.find(
       { zipcode: { $in: [ "10451", "10458", "10467", "10461", "10462" ] } }
    )

0
投票

因为您仅在一个文档中具有data字段。因此,如果在$in中运行$match,例如{$match : {$in : ['$zipcode', '$data']}},则会抛出相同的错误"errmsg" : "$in needs an array"

但是为什么?

[通常,Aggregation pipeline stages对收集文档执行原子操作,因此每个文档都不能使用,因此不能使用一个文档的字段取代其他文档。 (<< [Ex:-如果尝试$addFields添加从$data提取的新字段'dataCopy'-addFields不会向文档中不存在'data'字段的任何新字段添加)。因此,为了执行此操作,您需要使用$group将集合中的所有文档带到一个文档中,请尝试下面的聚合查询:

db.collection.aggregate([ /** Iterate on all docs & push document which has 'data' field into 'dataDoc' & * push all other docs into 'allDocs' array field */ { $group: { _id: "", dataDoc: { $push: { $cond: [{ $eq: [{ $type: "$data" }, "array"] }, "$$ROOT", "$$REMOVE"] } }, allDocs: { $push: { $cond: [ { $eq: [{ $type: "$zipcode" }, "string"] }, "$$ROOT", "$$REMOVE" ] } } } }, /** Unwind dataDoc array to make it 'dataDoc' field of type object */ { $unwind: "$dataDoc" }, /** Re-create 'allDocs' array field with objects which meet required condition, * newly formed array will have docs whose zipcode exists in data array * */ { $addFields: { allDocs: { $filter: { input: "$allDocs", cond: { $in: ["$$this.zipcode", "$dataDoc.data"] } } } } }, /** Unwind 'allDocs' array */ { $unwind: "$allDocs" }, /** Make 'allDocs' object field as new root, after this your result will have docs * whose zipcode exists in data array */ { $replaceRoot: { newRoot: "$allDocs" } } ]);

Test:

MongoDB-Playground
© www.soinside.com 2019 - 2024. All rights reserved.