如何在过滤数组时包含空数组
这是我的物品模型。
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
。 不同之处在于它的效率更高,并保留(或产生)一个没有任何问题的空数组。