I am new to MongoDB. I have a typical use case. Here is my single document JSON structure.
{
"category":"cat_1",
"_id": "id1",
"levels":[
{
"id":"l1",
"orders":[
{
"id":"o1",
"screens":[
{
"id":"l1o1s1",
"name":"screen1"
},
{
"id": "l1o1s2",
"name": "screen2"
}
]
},
{
"id": "o2",
"screens": [
{
"id": "l1o2s1",
"name": "screen3"
},
{
"id": "l1o2s2",
"name": "screen4"
}
]
}
]
},
{
"id": "l2",
"orders": [
{
"id": "o1",
"screens": [
{
"id": "l2o1s1",
"name": "screen5"
},
{
"id": "l2o1s2",
"name": "screen6"
}
]
},
{
"id": "o2",
"screens": [
{
"id": "l2o2s1",
"name": "screen7"
},
{
"id": "l2o2s2",
"name": "screen8"
}
]
}
]
}
]
}
Here I want to get the data of only given screen ids. For example, If ["l1o1s1","l1o2s2","l2o1s1","l2o2s1"] is my list of screen ids should find in the document,
then I want the result as below (It should return the screen id's only given in the input)
{
"category":"cat_1",
"_id": "id1",
"levels":[
{
"id":"l1",
"orders":[
{
"id":"o1",
"screens":[
{
"id":"l1o1s1",
"name":"screen1"
}
]
},
{
"id": "o2",
"screens": [
{
"id": "l1o2s2",
"name": "screen4"
}
]
}
]
},
{
"id": "l2",
"orders": [
{
"id": "o1",
"screens": [
{
"id": "l2o1s1",
"name": "screen5"
},
]
},
{
"id": "o2",
"screens": [
{
"id": "l2o2s1",
"name": "screen7"
}
]
}
]
}
]
}
the inputs of screens need not be only in a single document. It may exist in the other categories too. then It should return that documents only with the mentioned screen ids.
any idea to retrieve the data like this?
As @alex-blex suggested, your schema doesnt support that kind of queries, but if you still want to achieve your result, you can try with aggregation pipeline, but might not be efficient.
You can try below aggregation pipeline:
This is a really large and complex aggregation pipeline, as a result performance and efficiency is not gurranteed, but you can check if this works for you.
Explanation:
$match to filter out your desired set of documents only for later stages of aggregation pipeline.
$unwind to unwind the
levelsarray$unwind to unwind the
ordersarray$unwind to unwind the
screensarray$match to get the exact
screenswhich is required$replaceRoot to re-structre the JSON document, so that we can group back the unwinded arrays
$group to group the
screensto screens array$project to again restructure the resultant documents, to get out original structure back
$group to group the
ordersto orders array$project to again restructure the resultant documents, to get out original structure back
$group to group the
levelsto levels array and get back our final resultYou can check the results on this Mongo Playground
Alternatively, You can run the agreation pipeline up until stage 5, and then combine the result back into the format you want in your backend code.