如何在过滤数组时包含空数组

这是我的物品模型。

const itemSchema = new Schema({ name: String, category: String, occupied: [Number], active: { type: Boolean, default: true }, }); 

我想过滤“占用”arrays。 所以我使用聚合和放松'占领'领域。

所以我适用匹配查询。 并由_id分组。 但是如果过滤的“占用”数组是空的,则该项目消失。

这是我的代码

 Item.aggregate([ { $match: { active: true }}, { $unwind: "$occupied", }, { $match: { $and: [ { occupied: { $gte: 100 }}, { occupied: { $lt: 200 }} ]}}, { $group : { _id: "$_id", name: { $first: "$name"}, category: { $first: "$category"}, occupied: { $addToSet : "$occupied" } }} ], (err, items) => { if (err) throw err; return res.json({ data: items }); }); 

这里是示例数据集

 { "_id" : ObjectId("59c1bced987fa30b7421a3eb"), "name" : "printer1", "category" : "printer", "occupied" : [ 95, 100, 145, 200 ], "active" : true }, { "_id" : ObjectId("59c2dbed992fb91b7421b1ad"), "name" : "printer2", "category" : "printer", "occupied" : [ ], "active" : true } 

上面的查询结果

 [ { "_id" : ObjectId("59c1bced987fa30b7421a3eb"), "name" : "printer1", "category" : "printer", "occupied" : [ 100, 145 ], "active" : true } ] 

和我想要的结果

 [ { "_id" : ObjectId("59c1bced987fa30b7421a3eb"), "name" : "printer1", "category" : "printer", "occupied" : [ 100, 145 ], "active" : true }, { "_id" : ObjectId("59c2dbed992fb91b7421b1ad"), "name" : "printer2", "category" : "printer", "occupied" : [ ], "active" : true } ] 

我怎么能这样做?

提前致谢。

在最简单的forms中,你保持它简单地通过首先不使用$unwind 。 所应用的条件意味着您正在寻找与特定值匹配的“唯一集合”。

为此,你使用$filter ,像$setUnion这样的“set operator”将input值减less到“set”

 Item.aggregate([ { "$match": { "active": true } }, { "$project": { "name": 1, "category": 1, "occupied": { "$filter": { "input": { "$setUnion": [ "$occupied", []] }, "as": "o", "cond": { "$and": [ { "$gte": ["$$o", 100 ] }, { "$lt": ["$$o", 200] } ] } } } }} ], (err, items) => { if (err) throw err; return res.json({ data: items }); }); 

自从MongoDB v3以来,两者都已经出现,所以这样做是非常普遍的做法。

如果由于某种原因你还在使用MongoDB 2.6,那么你可以使用$map$setDifference来代替:

 Item.aggregate([ { "$match": { "active": true } }, { "$project": { "name": 1, "category": 1, "occupied": { "$setDifference": [ { "$map": { "input": "$occupied", "as": "o", "in": { "$cond": { "if": { "$and": [ { "$gte": ["$$o", 100 ] }, { "$lt": ["$$o", 200] } ] }, "then": "$$o", "else": false } } }}, [false] ] } }} ], (err, items) => { if (err) throw err; return res.json({ data: items }); }); 

这与将数组分开,过滤项目并使用$addToSet将其重新组合在一起的结果是$addToSet 。 不同之处在于它的效率更高,并保留(或产生)一个没有任何问题的空数组。