Как создать агрегированный запрос mongodb в python для документов, содержащих вложенный список документов?

У меня есть коллекция mongoDB с документами, которые выглядят так:

{
    "_id" : "132743",
    "RECORD_DATA" : [ 
        {
            "FIELD_TYPE" : "Primary",
            "DATA" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec blandit leo sit amet nisi ultricies bibendum. Aenean efficitur pharetra diam, non pretium nisi blandit eu. Maecenas eget dolor sed ipsum semper posuere id eget purus. Ut tempor massa vel porta euismod. Vivamus et elementum justo. Aliquam porta, ipsum at semper pulvinar, turpis ipsum congue orci, a fringilla turpis arcu eget lorem. Vestibulum consectetur sapien neque, at vulputate mi congue vitae.",
            "DETAIL" : "XYZ"
        },  
        {
            "FIELD_TYPE" : "Secondary",
            "DATA" : "Nullam congue aliquam risus. Aenean semper ut elit id viverra. Mauris tincidunt non justo et tempor. Donec non tempus sapien. Curabitur facilisis risus tortor, nec bibendum libero feugiat sed. Curabitur eu quam ac mi sodales ultricies. Cras posuere tincidunt faucibus.",
            "DETAIL" : "XYZ"
        },
        {
            "FIELD_TYPE" : "Secondary",
            "DATA" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. ",
            "DETAIL" : "ABC"
        }, 
        {
            "FIELD_TYPE" : "Secondary",
            "DATA" : "Maecenas volutpat facilisis tortor sed pellentesque. Quisque tristique sem sit amet ipsum convallis porttitor. Vestibulum a tempus ex. Donec molestie tortor est, sed malesuada sapien maximus vel.",
            "DETAIL" : "ABC"
        },
        {
            "FIELD_TYPE" : "optional1",
            "DATA" : "Curabitur faucibus dolor nisl, at venenatis tortor fermentum at. Vestibulum sodales posuere neque id aliquet. Aliquam dignissim ex quis lacus fermentum, at consectetur nunc viverra. ",
            "DETAIL" : "XYZ"
        }, 
        {
            "FIELD_TYPE" : "optional2",
            "DATA" : "Cras vulputate lacinia elit, eu fringilla neque imperdiet eget. Nam placerat venenatis felis at pharetra. Praesent vestibulum ligula sit amet elit dignissim suscipit. ",
            "DETAIL" : "QWE"
        }
    ]
}

Я хочу извлечь одно поле из RECORD_DATA, в котором для FIELD_TYPE установлено значение Primary вместе с _id для каждого документа в коллекции. Мой окончательный результат должен выглядеть так:

{
    "_id" : "132743",
    "DATA" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec blandit leo sit amet nisi ultricies bibendum. Aenean efficitur pharetra diam, non pretium nisi blandit eu. Maecenas eget dolor sed ipsum semper posuere id eget purus. Ut tempor massa vel porta euismod. Vivamus et elementum justo. Aliquam porta, ipsum at semper pulvinar, turpis ipsum congue orci, a fringilla turpis arcu eget lorem. Vestibulum consectetur sapien neque, at vulputate mi congue vitae."
}

Я попробовал запрос агрегирования:

MongoDatabase.db[collection].aggregate([{$project:{'DATA':'$RECORD_DATA.DATA'}},{$match:{'RECORD_DATA.FIELD_TYPE':"Primary"}}])

Это не дает мне никаких результатов. Может ли кто-нибудь помочь мне создать для него запрос?

1
0
44
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

попробуйте этот запрос:

db.collection.aggregate([{
    "$unwind": "$RECORD_DATA"
}, {
    "$match": {
        "RECORD_DATA.FIELD_TYPE": "Primary"
    }
}, {
    "$project": {
        "_id": 1,
        "DATA": "$RECORD_DATA.DATA"
    }
}])

вы можете попробовать это онлайн здесь: mongoplayground.net/p/1HY-GSMnzoX

Ответ принят как подходящий

Вы можете использовать комбинацию операторов массива $arrayElemAt, $map и $filter для достижения желаемого результата.

Выражение с оператором $filter отфильтрует массив RECORD_DATA, чтобы в нем были только документы со значением FIELD_TYPE"Primary".

Оператор $map затем отобразит результат, возвращенный выше, чтобы просто вывести массив одиночных значений DATA. Затем $arrayElemAt вернет первый элемент из этого списка, который затем может быть спроецирован.

Следующее демонстрирует вышесказанное:

MongoDatabase.db[collection].aggregate([
    { "$match": { "RECORD_DATA.FIELD_TYPE": "Primary" } },
    { "$project": {
        "DATA": {
            "$arrayElemAt": [
                {
                    "$map": {
                        "input": {
                            "$filter": {
                                "input": "$RECORD_DATA",
                                "as": "record",
                                "cond": { "$eq": ["$$record.FIELD_TYPE", "Primary"] }
                            }
                        },
                        "as": "el",
                        "in": "$$el.DATA"
                    }
                },
                0
            ]
        }
    } }
])

Спасибо. Это дает ожидаемые результаты.

Deepak Aggarwal 12.04.2018 07:09
db.collection.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $match: {
                RECORD_DATA: {
                    $elemMatch: {
                        FIELD_TYPE: "Primary"
                    }
                }
            }
        },

        // Stage 2
        {
            $project: {
                'RECORD_DATA': {
                    $arrayElemAt: [{
                        $filter: {
                            input: '$RECORD_DATA',
                            as: "data",
                            cond: {
                                $eq: ["$$data.FIELD_TYPE", 'Primary']
                            }
                        }
                    }, 0]
                }

            }
        },

        // Stage 3
        {
            $project: {
                _id: 1,
                DATA: '$RECORD_DATA.DATA'
            }
        }

    ]


);

Другие вопросы по теме