Подсчет агрегации вложенных объектов MongoDB

у меня есть высоко вложенный набор объектов mongoDB, и я хочу подсчитать количество вложенных документов, которые соответствуют заданному условию Edit: (в каждом документе). Например:

{"_id":{"chr":"20","pos":"14371","ref":"A","alt":"G"},
"studies":[
    {
        "study_id":"Study1",
        "samples":[
            {
                "sample_id":"NA00001",
                "formatdata":[
                    {"GT":"1|0","GQ":48,"DP":8,"HQ":[51,51]}
                ]
            },
            {
                "sample_id":"NA00002",
                "formatdata":[
                    {"GT":"0|0","GQ":48,"DP":8,"HQ":[51,51]}
                ]
            }
        ]
    }
]
}
{"_id":{"chr":"20","pos":"14372","ref":"T","alt":"AA"},
"studies":[
    {
        "study_id":"Study3",
        "samples":[
            {
                "sample_id":"SAMPLE1",
                "formatdata":[
                    {"GT":"1|0","GQ":48,"DP":8,"HQ":[51,51]}
                ]
            },
            {
                "sample_id":"SAMPLE2",
                "formatdata":[
                    {"GT":"1|0","GQ":48,"DP":8,"HQ":[51,51]}
                ]
            }
        ]
    }
]
}
{"_id":{"chr":"20","pos":"14373","ref":"C","alt":"A"},
"studies":[
    {
        "study_id":"Study3",
        "samples":[
            {
                "sample_id":"SAMPLE3",
                "formatdata":[
                    {"GT":"0|0","GQ":48,"DP":8,"HQ":[51,51]}
                ]
            },
            {
                "sample_id":"SAMPLE7",
                "formatdata":[
                    {"GT":"0|0","GQ":48,"DP":8,"HQ":[51,51]}
                ]
            }
        ]
    }
]
}

Я хочу знать, сколько вложенных документов содержит GT: "1/0", который в этом случае будет 1 в первом документе, и два во втором, и 0 в 3-м. Я пробовал функции unwind и aggregate, но я, очевидно, не делаю что-то правильное. Когда я пытаюсь подсчитать документы sub по полю " GT " монго жалуется:

db.collection.aggregate([{$group: {"$studies.samples.formatdata.GT":1,_id:0}}])

поскольку имена моей группы не могут содержать ".- но если я их опущу ... --6-->

db.collection.aggregate([{$group: {"$GT":1,_id:0}}])

он жалуется, потому что "$GT не может быть именем оператора"

какие идеи?

1 ответов


вам нужно $unwind при работе с массивами, и вам нужно сделать это три раза:

 db.collection.aggregate([

     // Un-wind the array's to access filtering 
     { "$unwind": "$studies" },
     { "$unwind": "$studies.samples" },
     { "$unwind": "$studies.samples.formdata" },

     // Group results to obtain the matched count per key
     { "$group": {
         "_id": "$studies.samples.formdata.GT",
         "count": { "$sum": 1 }
     }}
 ])

В идеале вы хотите отфильтровать свой вход. Возможно, сделайте это с помощью $match как до, так и после $unwind обрабатывается и использует $регулярное выражение для сопоставления документов, где данные в точке начинается с "1".

 db.collection.aggregate([

     // Match first to exclude documents where this is not present in any array member
     { "$match": { "studies.samples.formdata.GT": /^1/ } },

     // Un-wind the array's to access filtering 
     { "$unwind": "$studies" },
     { "$unwind": "$studies.samples" },
     { "$unwind": "$studies.samples.formdata" },

     // Match to filter
     { "$match": { "studies.samples.formdata.GT": /^1/ } },

     // Group results to obtain the matched count per key
     { "$group": {
         "_id": {
              "_id": "$_id",
              "key": "$studies.samples.formdata.GT"
         },
         "count": { "$sum": 1 }
     }}
 ])

обратите внимание, что во всех случаях префиксные записи "доллар $" являются " переменными" ссылка на свойства документа. Это "значения" для использования ввода с правой стороны. Левая сторона "keys" должна быть указана как простая строковая клавиша. Никакая переменная не может использоваться для имени ключа.