2015-01-13 20 views
6

Mam wysoce zagnieżdżony zestaw obiektów mongoDB i chcę policzyć liczbę poddokumentów pasujących do danego warunku. Edytuj: (w każdym dokumencie). Na przykład:Agregacja zagnieżdżonych obiektów MongoDB zliczająca

{"_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]} 
       ] 
      } 
     ] 
    } 
] 
} 

chcę wiedzieć ile Dokumenty podrzędne zawierają GT: „1 | 0”, która w tym przypadku byłoby 1 w pierwszym dokumencie, a dwie w drugim, a 0 w 3rd. Próbowałem odwijania i agregowania funkcji, ale oczywiście nie robię czegoś poprawnego. Kiedy próbuję policzyć dokumenty podrzędne przez „GT” pola, Mongo narzeka:

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

od nazw moja grupa nie może zawierać, ale jeśli pozostawić je na zewnątrz „”:

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

to narzeka, ponieważ "$ GT nie może być nazwą operatora"

Jakieś pomysły?

Odpowiedz

14

trzeba przetwarzać $unwind podczas pracy z tablicami, i trzeba zrobić to trzy razy:

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

Idealnie chcesz filtrować wejście. Prawdopodobnie rób to z $match zarówno przed, jak i po tym, jak $ unwind jest przetwarzane i przy użyciu $regex, aby dopasować dokumenty, w których dane w punkcie rozpoczynają się od "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 } 
    }} 
]) 

Należy zauważyć, że we wszystkich przypadkach „dollar $” prefiksem wpisy są „zmienne” odnoszące się do właściwości dokumentu. Są to "wartości", aby użyć danych wejściowych po prawej stronie. Lewe "klucze" muszą być określone jako zwykły ciąg znaków. Żadnej zmiennej nie można użyć do nazwania klucza.

+1

Tak, to działa, ale w rzeczywistości liczy wszystkie wartości w kolekcji zamiast w dokumencie. To, czego szukam, to odpowiednik zliczania dokumentów podrzędnych w każdym dokumencie, w tym jeśli jest ich 0. Będę edytować mój pierwotny post, aby było to bardziej jasne. –

+0

@StevenHart To nie było jasne w twoim pytaniu. Ale jest to prosta sprawa włączenia identyfikatora dokumentu do klucza grupowania. Zobacz zmianę. –

+0

Czy drugi $ mecz jest niezbędny po $ unwinds? – TheGaff

Powiązane problemy