Reputation: 10717
please, help , I have following type of documents:
db.g.find({_id:ObjectId("605929e0122984ad3c4c537a") }).pretty()
{
"_id" : ObjectId("605929e0122984ad3c4c537a"),
"a" : [
{
"p" : [
{
"pid" : 1,
"c" : {
"t" : [
{
"x" : 1,
"y" : 2
},
{
"z" : 1,
"x" : 5
},
{
"h" : 1
}
]
}
},
{
"d" : 1
}
]
},
{
"p" : [
{
"pid" : 2,
"c" : {
"t" : [
{
"x" : 4
}
]
}
},
{
"pid" : 3,
"c" : {
"t" : [
{
"y" : 4
}
]
}
}
]
}
]
}
And I need to fetch only the values from the fields:"a.p.pid" , and all "x" or "y" if they exist , so the final result to look like:
{pid:1,x:1,y:2}
{pid:1,x:5}
{pid:2,x:4}
{pid:3,y:4}
Collection is pretty big and doing 3x$unwind take alot of time ... Attempting with $redact, $map / $filter but no success ... , any help will be highly appreciated ...
Upvotes: 0
Views: 51
Reputation: 57095
Demo - https://mongoplayground.net/p/w0wWJRdBP-J
Use $unwind twice to seperate each pid
element
Use $filter to get an array of objects where x or y is present.
db.collection.aggregate([
{ "$unwind": "$a" },
{ "$unwind": "$a.p" },
{ "$project": {
_id: 0, pid: "$a.p.pid",
t: {
$filter: { input: "$a.p.c.t", as: "item",
cond: { $or: [
{ $ne: [ { $type: "$$item.x" }, "missing" ] },
{ $ne: [ { $type: "$$item.y" }, "missing" ]}
]}
}
}}
},
{ "$unwind": "$t" },
{ "$project": { pid: 1, x: "$t.x", y: "$t.y" } }
])
Upvotes: 2