i have this json :
{
"_id": "id",
"field1": "value1",
"field2": "value2",
"field3": "value3",
"field4": "value4",
"field5": "value5",
"field6": [
{
"field7": "value_a7_level1",
"field8": "value_a8_level1",
"field9": "value_a9_level1",
"field10": [
{
"field11": "value_a11_level1",
"field12": "value_a12_level1",
"field13": "value_a13_level1",
"field14": "value_a14_level1"
},
{
"field11": "value_b11_level1",
"field12": "value_b12_level1",
"field13": "value_b13_level1",
"field14": "value_b14_level1"
}
],
"field15": [
{
"field16": "zzz",
"field17": "xxx",
"field18": "value_a18_level1",
"field19": "value_a19_level1"
},
{
"field16": "xxx",
"field17": "yyy",
"field18": "value_b18_level1",
"field19": "value_b19_level1"
},
{
"field16": "xxx",
"field17": "yyy",
"field18": "value_c18_level1",
"field19": "value_c19_level1"
}
]
},
{
"field7": "value_a7_level2",
"field8": "value_a8_level2",
"field9": "value_a9_level2",
"field10": [
{
"field11": "value_a11_level2",
"field12": "value_a12_level2",
"field13": "value_a13_level2",
"field14": "value_a14_level2"
},
{
"field11": "value_b11_level2",
"field12": "value_b12_level2",
"field13": "value_b13_level2",
"field14": "value_b14_level2"
}
],
"field15": [
{
"field16": "value_a16_level2",
"field17": "value_a17_level2",
"field18": "value_a18_level2",
"field19": "value_a19_level2"
},
{
"field16": "value_b16_level2",
"field17": "value_b17_level2",
"field18": "value_b18_level2",
"field19": "value_b19_level2"
},
{
"field16": "value_c16_level2",
"field17": "value_c17_level2",
"field18": "value_c18_level2",
"field19": "value_c19_level2"
}
]
},
{
"field7": "value_a7_level3",
"field8": "value_a8_level3",
"field9": "value_a9_level3",
"field10": [
{
"field11": "value_a11_level3",
"field12": "value_a12_level3",
"field13": "value_a13_level3",
"field14": "value_a14_level3"
},
{
"field11": "value_b11_level3",
"field12": "value_b12_level3",
"field13": "value_b13_level3",
"field14": "value_b14_level3"
}
],
"field15": [
{
"field16": "xxx",
"field17": "yyy",
"field18": "value_a18_level3",
"field19": "value_a19_level3"
},
{
"field16": "value_b16_level3",
"field17": "value_b17_level3",
"field18": "value_b18_level3",
"field19": "value_b19_level3"
},
{
"field16": "value_c16_level3",
"field17": "value_c17_level3",
"field18": "value_c18_level3",
"field19": "value_c19_level3"
}
]
}
],
"field20": [
{
"field21": "value21_level1",
"field22": "value22_level1",
"field23": "value23_level1"
},
{
"field21": "value21_level2",
"field22": "value22_level2",
"field23": "value23_level2"
}
]
}
I want to return a result according to filters and selections. The filters would be for example:
field16 and field17 must be equal to "XXX" and "YYY" respectively.
I need to return a json that will contain all the fields but field15 will only contain the objects corresponding to the filters. Also field6 will only contain the objects for which chemp15 returns true to the filters.
In my example I will have this result:
{
"_id": "id",
"field1": "value1",
"field2": "value2",
"field3": "value3",
"field4": "value4",
"field5": "value5",
"field6": [
{
"field7": "value_a7_level1",
"field8": "value_a8_level1",
"field9": "value_a9_level1",
"field10": [
{
"field11": "value_a11_level1",
"field12": "value_a12_level1",
"field13": "value_a13_level1",
"field14": "value_a14_level1"
},
{
"field11": "value_b11_level1",
"field12": "value_b12_level1",
"field13": "value_b13_level1",
"field14": "value_b14_level1"
}
],
"field15": [
{
"field16": "xxx",
"field17": "yyy",
"field18": "value_b18_level1",
"field19": "value_b19_level1"
},
{
"field16": "xxx",
"field17": "yyy",
"field18": "value_c18_level1",
"field19": "value_c19_level1"
}
]
},
{
"field7": "value_a7_level3",
"field8": "value_a8_level3",
"field9": "value_a9_level3",
"field10": [
{
"field11": "value_a11_level3",
"field12": "value_a12_level3",
"field13": "value_a13_level3",
"field14": "value_a14_level3"
},
{
"field11": "value_b11_level3",
"field12": "value_b12_level3",
"field13": "value_b13_level3",
"field14": "value_b14_level3"
}
],
"field15": [
{
"field16": "xxx",
"field17": "yyy",
"field18": "value_a18_level3",
"field19": "value_a19_level3"
}
]
}
],
"field20": [
{
"field21": "value21_level1",
"field22": "value22_level1",
"field23": "value23_level1"
},
{
"field21": "value21_level2",
"field22": "value22_level2",
"field23": "value23_level2"
}
]
}
I tried several ways to get this result but in vain. Here is the last one but I am not satisfied at all because the result is not well structured:
db.requirements.aggregate([
{
$match: {
"field6": {
$elemMatch: {
"field15": {
$elemMatch: {
"field16": "xxx",
"field17": "yyy",
}
}
}
}
}
},
{
$addFields: {
"field6": {
$map: {
input: "$field6",
as: "f6",
in: {
$filter: {
input: "$$f6.field15",
as: "f15",
cond: {$and: [
{$eq: ["$$f15.f16", "xxx"]},
{$eq: ["$$f15.f17", "yyy"]}
]}
}
}
}
}
},
}
]);
I also tried with $unwind and $group but it doesn't return the json I want.
Can someone help me find the solution?
Thank you in advance for your answers.
Use
$reduce
as a loop.Alternately, if many more conditions need to applied to
field6
, it might be easier to$unwind
onfield6
first to isolate further operations on the fields inside that doc. Note however that$unwind
and$group
could have performance impact iffield6
is a lengthy array.