Ihor Patychenko
Ihor Patychenko

Reputation: 196

Retrieve only the queried object from nested array in MongoDB

Having the following document in my Mongo I'm trying to get the object with specified id. Here is my Mongo document. Mongo version: 2.6

{
    "_id" : ObjectId("57c1ae9ac1bd31d4eb4d546d"),
    "footers" : [ 
        {
            "type" : "web",
            "rows" : [ 
                {
                    "id" : "abc",
                    "elements" : [ 
                        {
                            "id" : "def",
                            "type" : "image",
                            "url" : "http://example.com"
                        }, 
                        {
                            "id" : "ghi",
                            "type" : "image",
                            "url" : "http://example.com"
                        }
                    ]
                }
            ]
        }
    ]
}

I'm looking for an object with id "def", and I want to obtain this result:

{
    "id" : "def",
    "type" : "image",
    "url" : "http://example.com"
}

Below I cite the example of code that I tried to make search of this object.

db.getCollection('myCollection').aggregate([
    {"$match": {
        "footers.rows.elements.id": "def"
    }},
    {"$group": {
        "_id": "$footers.rows.elements"
    }}
])

And the result is:

{
    "_id" : [ 
        [ 
            [ 
                {
                    "id" : "def",
                    "type" : "image",
                    "url" : "http://example.com"
                }, 
                {
                    "id" : "ghi",
                    "type" : "image",
                    "url" : "http://example.com"
                }
            ]
        ]
    ]
}

Any suggestions?

Upvotes: 1

Views: 306

Answers (1)

Adi Fatol
Adi Fatol

Reputation: 964

You need to use "$unwind".

This answer will help you with more details Mongodb unwind nested documents (https://stackoverflow.com/a/12241733/224743 specifies this should work in MongoDB 2.2+)

For your specific example, you could do something like:

db.getCollection('myCollection').aggregate([
    {"$match"  : { "footers.rows.elements.id": "def" }}, 
    {"$unwind" : "$footers"}, 
    {"$unwind" : "$footers.rows"}, 
    {"$unwind" : "$footers.rows.elements"}, 
    {"$group"  : { "_id": "$footers.rows.elements" }}, 
    {"$match"  : { "_id.id": "def" }}
]);

Notice the multiple "$unwind" chainings and also the final "$match" which is needed to reapply the conditions for the $unwind-ed documents.

Upvotes: 2

Related Questions