这是我的项目模型。
const itemSchema = new Schema({
name: String,
category: String,
occupied: [Number],
active: { type: Boolean, default: true },
});
我想过滤掉“被占用的”#39;阵列。因此,我使用聚合和放松占用'字段。
所以我应用匹配查询。并按_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
}
]
我怎么能这样做?
提前致谢。
答案 0 :(得分:0)
在最简单的形式中,您只需首先不使用$unwind
即可。您的条件意味着您正在寻找"独特的套装"匹配到特定值。
为此,您使用$filter
和"设置运算符"像$setUnion
一样将输入值减少到" 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
一起重新组合。不同之处在于它的效率更高,并且保留(或生成)一个没有任何问题的空数组。