[英]How to return an array of subdocuments that match a given criteria in Mongodb?
Given a collection like: 鉴于如下集合:
{
"_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")
}
I need to get all Zone ids and codes that have the IsAvailable flag set to true. 我需要获取IsAvailable标志设置为true的所有Zone ID和代码。
I have tried the following: 我尝试过以下方法:
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);
This gives me 这给了我
{
"0" : {
"Id": 1,
"Code": "XXXXXXXX",
"IsAvailable": true
},
"1" : {
"Id": 45,
"Code": "ZZZZZZZZZ",
"IsAvailable": false
}
}
But I just want only where the IsAvailable flag is set to true returned. 但我只想要将IsAvailable标志设置为true的地方返回。
Am I going about this the wrong way?? 我错了吗? I tried using aggregate but ran into the same problem - returning all and not filtering the IsAvailable flag.
我尝试使用聚合但遇到了同样的问题 - 返回所有并且不过滤IsAvailable标志。
You need to use the .aggregate()
method. 您需要使用
.aggregate()
方法。
First of all you need to reduce the size of the documents to process using the $match
operator. 首先,您需要使用
$match
运算符减小要处理的文档的大小。 From there you will need to denormalize your "PersonalDetails" array using the $unwind
operator. 从那里你需要使用
$unwind
运算符对你的“PersonalDetails”数组进行反规范化。
You can then use the $project
operator to return only sub-documents that match your criteria. 然后,您可以使用
$project
运算符仅返回符合条件的子文档。
The $map
operator in the project stage is used to return array of sub-documents. 项目阶段中的
$map
运算符用于返回子文档数组。
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]
]
}
}}
])
Which returns: 哪个回报:
{
"_id" : "XXXX",
"zone" : [
{
"Id" : 1,
"Code" : "XXXXXXXX",
"IsAvailable" : true
}
]
}
Starting from MongoDB 3.2 we can use the $filter
operator to do this efficiently 从MongoDB 3.2开始,我们可以使用
$filter
运算符来有效地执行此操作
db.collection.aggregate([
{ "$match": {
"JobId": 100,
"PersonalDetails.Zone.IsAvailable": true
}},
{ "$unwind": "$PersonalDetails" },
{ "$project": {
"zone": {
"$filter": {
"input": "$PersonalDetails.Zone",
"as": "z", "cond": "$$z.IsAvailable"
}
}
}}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.