Reputation: 1088
I have documents in a collection in following format :
{"hourNo":"0","errorSegments":[
{
"errorSegmentId" : "1019",
"errorCode" : "401"
},
{
"errorSegmentId" : "1022",
"errorCode" : "402"
},
{
"errorSegmentId" : "1010",
"errorCode" : "405"
}
]}
{"hourNo":"1","errorSegments":[
{
"errorSegmentId" : "1011",
"errorCode" : "405"
},
{
"errorSegmentId" : "1055",
"errorCode" : "405"
},
{
"errorSegmentId" : "1033",
"errorCode" : "405"
},
{
"errorSegmentId" : "1042",
"errorCode" : "408"
}
]}
First criteria to match is the hourNo , as there will be other documents with different hour numbers.
The final output required is sub-array of the sub-document that has "errorSegmentId", "errorCode" that matches the criteria of certain errorCode .
For example :
Getting all the errorSegments that are in hour 1 that have errorCode 405 .
So the output would be :
{
"errorSegmentId" : "1011",
"errorCode" : "405"
},
{
"errorSegmentId" : "1055",
"errorCode" : "405"
},
{
"errorSegmentId" : "1033",
"errorCode" : "405"
}
=============================================================
I have tried few aggregation operations , but i am not able to get desired result .
TIA.
Upvotes: 0
Views: 288
Reputation: 38992
In an aggregation pipeline match all documents where hourNo
is 0
.
Then unwind errorSegments
array into individual documents.
Query the resulting documents for documents where errorSegments.errorCode
is 405
.
Lastly, replaceRoot
.
db.test.aggregate([
{$match: {"hourNo": "0"}},
{$unwind: "$errorSegments"},
{$match: {"errorSegments.errorCode": "405"}},
{$replaceRoot: {newRoot: "$errorSegments"}}
])
Sample query results:
{ "errorSegmentId" : "1011", "errorCode" : "405" }
{ "errorSegmentId" : "1055", "errorCode" : "405" }
{ "errorSegmentId" : "1033", "errorCode" : "405" }
Upvotes: 1
Reputation: 75994
You can use below aggregation in 3.4.
$match
to only filters documents where there exists errorSegments array with at least one errorCode matching input error code.
$filter
the errorSegments to only contain errorSegment matching from input error code followed by $unwind
and $replaceRoot
to promote the matching values to the top.
db.col.aggregate([
{"$match":{"hourNo":"1","errorSegments.errorCode":"405"}},
{"$project":{
"errorSegments":{
"$filter":{
"input":"$errorSegments",
"as":"e",
"cond":{"$eq":["$$e.errorCode","405"]}
}
}
}},
{"$unwind":"$errorSegments"},
{"$replaceRoot": {"newRoot":"$errorSegments"}}
])
Upvotes: 1