给出类似的集合:
{
"_id": "XXXX",
"JobId": [
100
],
"PersonalDetails": [
{
"Level": 1,
"Zone": [
{
"Id": 1,
"Code": "XXXXXXXX",
"IsAvailable": true
},
{
"Id": 45,
"Code": "ZZZZZZZZZ",
"IsAvailable": false
}
]
}
],
"Timestamp": ISODate("2015-11-01T00:00:00.000Z")
}
我需要获取将IsAvailable标志设置为true的所有Zone ID和代码。
我尝试了以下内容:
var details = db.test.find(
{
JobId: {$in: [100]},
'PersonalDetails': {$elemMatch: {Zone : {$elemMatch: {IsAvailable: true}}}}
},
{
'PersonalDetails.Zone.Id': 1,
'PersonalDetails.Zone.Code': 1,
'PersonalDetails.Zone.IsAvailable': 1
});
details.forEach(function(doc){
var myDetails = doc.PersonalDetails;
myDetails.forEach(function(doc2){
var myZones = doc2.Zone;
print(myZones);
这给了我
{
"0" : {
"Id": 1,
"Code": "XXXXXXXX",
"IsAvailable": true
},
"1" : {
"Id": 45,
"Code": "ZZZZZZZZZ",
"IsAvailable": false
}
}
但我只想要将IsAvailable标志设置为true的地方返回。
我是否以错误的方式解决这个问题?我尝试使用聚合但遇到了同样的问题 - 返回所有并且不过滤IsAvailable标志。
答案 0 :(得分:3)
您需要使用http://schemas.opengis.net/wfs/1.1.0/wfs.xsd方法。
首先,您需要使用.aggregate()
运算符缩小要处理的文档的大小。从那里你需要使用$match
运算符对你的“PersonalDetails”数组进行反规范化。
然后,您可以使用$unwind
运算符仅返回符合条件的子文档。
项目阶段的$project
运算符用于返回子文档数组。
db.collection.aggregate([
{ "$match": {
"JobId": 100,
"PersonalDetails.Zone.IsAvailable": true
}},
{ "$unwind": "$PersonalDetails" },
{ "$project": {
"zone": {
"$setDifference": [
{ "$map": {
"input": "$PersonalDetails.Zone",
"as": "z",
"in": { "$cond": [ "$$z.IsAvailable", "$$z", false ] }
}},
[false]
]
}
}}
])
返回:
{
"_id" : "XXXX",
"zone" : [
{
"Id" : 1,
"Code" : "XXXXXXXX",
"IsAvailable" : true
}
]
}
从MongoDB 3.2开始,我们可以使用$map
运算符来有效地执行此操作
db.collection.aggregate([
{ "$match": {
"JobId": 100,
"PersonalDetails.Zone.IsAvailable": true
}},
{ "$unwind": "$PersonalDetails" },
{ "$project": {
"zone": {
"$filter": {
"input": "$PersonalDetails.Zone",
"as": "z", "cond": "$$z.IsAvailable"
}
}
}}
])