Как мне сопоставить массив поддокументов в MongoDB? - PullRequest
2 голосов
/ 12 апреля 2019

Сопоставить документы, если значение в массиве вложенных документов больше некоторого значения, только если этот же документ содержит поле, равное некоторому значению

У меня есть коллекция, содержащая документы с массивомсубдокументов.Этот массив вложенных документов содержит поле, которое определяет, могу ли я фильтровать документы в коллекции на основе другого поля вложенного документа.Это будет иметь больше смысла, когда вы увидите пример документа.

    {  
    "_id":"ObjectId('XXX')",
    "Data":{  
        "A":"",
        "B":"-25.78562 ; 28.35629",
        "C":"165"
    },
    "SubDocuments":[  
        {  
            "_id":"ObjectId('XXX')",
            "Data":{  
                "Value":"XXX",
                "DataFieldId":"B"
            }
        },
        {  
            "_id":"ObjectId('XXX')",
            "Data":{  
                "Value":"",
                "DataFieldId":"A"
            }
        },
        {  
            "_id":"ObjectId('XXX')",
            "Data":{  
                "Value":"105",
                "DataFieldId":"Z"
            }
        }
    ]
}

Я хочу сопоставлять только те документы, которые содержат вложенные документы, с DataFieldId, равным Z, но также фильтровать значения, которыебольше 105, только если идентификатор поля данных равен Z.

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Попробуйте, как показано ниже:

db.collection.aggregate([
{
    $project: {
        _id:1,
        Data:1,
        filteredSubDocuments: {
            $filter: {
                input: "$SubDocuments",
                as: "subDoc",
                cond: { 
                    $and: [
                        { $eq: ["$$subDoc.Data.DataFieldId", "Z"] },
                        { $gte: ["$$subDoc.Data.Value", 105] }
                    ]
                }
            }
        }
    }
}
])

В результате ответ будет:

{
    "_id" : ObjectId("5cb09659952e3a179190d998"),
    "Data" : {
        "A" : "",
        "B" : "-25.78562 ; 28.35629",
        "C" : "165"
    },
    "filteredSubDocuments" : [
        {
            "_id" : "ObjectId('XXX')",
            "Data" : {
                "Value" : 105,
                "DataFieldId" : "Z"
            }
        }
    ]
}
0 голосов
/ 14 апреля 2019

Это можно сделать с помощью оператора $elemMatch на вложенных документах, для получения подробной информации вы можете нажать на предоставленную ссылку. Для вашей проблемы вы можете попробовать запрос ниже, используя $elemMatch, что проще, чем агрегация:

    db.collectionName.find({
    "SubDocuments": { 
        $elemMatch: {
            "Data.DataFieldId": "Z" , 
            "Data.Value" : {$gte: 105}  
        } 
    } })

Он работает нормально, я проверил его локально, одна из модификаций, которую вы требовали, заключается в том, что вы должны указать значение SubDocuments.Data.Value как Number или Long в соответствии с вашими требованиями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...