R2D2
R2D2

Reputation: 10717

Fetch values x,y from field in 3x nested arrays

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

Answers (1)

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

Related Questions