Получить только запрошенный объект из вложенного массива в MongoDB

Имея следующий документ в моем Mongo, я пытаюсь получить объект с указанным идентификатором. Вот мой документ Mongo. Версия монго: 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"
                        }
                    ]
                }
            ]
        }
    ]
}

Я ищу объект с идентификатором "def" и хочу получить такой результат:

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

Ниже я привожу пример кода, которым я пытался сделать поиск этого объекта.

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

И результат:

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

Какие-либо предложения?


person Ihor Patychenko    schedule 31.08.2016    source источник


Ответы (1)


Вам нужно использовать "$unwind".

Этот ответ поможет вам с более подробной информацией о раскрутке вложенных документов Mongodb (https://stackoverflow.com/a/12241733/224743 указывает, что это должно работать в MongoDB 2.2+)

Для вашего конкретного примера вы можете сделать что-то вроде:

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" }}
]);

Обратите внимание на несколько цепочек «$unwind», а также на финальное «$match», которое необходимо для повторного применения условий для документов с $unwind-ed.

person Adi Fatol    schedule 31.08.2016
comment
Большое спасибо. Очень полезно. - person Ihor Patychenko; 31.08.2016