2015-01-13 18 views
6

Ho un set di oggetti mongoDB altamente nidificato e voglio contare il numero di documenti parziali che corrispondono a una data condizione Modifica: (in ogni documento). Per esempio:Conteggio di aggregazione di oggetti nidificati MongoDB

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

Voglio sapere quanti documenti secondari contengono GT: "1 | 0", che in questo caso sarebbe 1 nel primo documento, e due nel secondo, e 0 nel 3 °. Ho provato le funzioni di svolgimento e aggregazione, ma ovviamente non sto facendo qualcosa di corretto. Quando provo a contare i documenti secondari dal campo "GT", Mongo si lamenta:

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

dal nome del mio gruppo non può contenere, ma se li lascio fuori "":

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

esso si lamenta perché "$ GT non può essere un nome di operatore"

Qualche idea?

risposta

14

è necessario elaborare $unwind quando si lavora con gli array, ed è necessario fare questo tre volte:

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

Idealmente si desidera filtrare il vostro input. È possibile farlo con un $match sia prima che dopo che $ unwind venga elaborato e utilizzando un valore $regex per abbinare i documenti in cui il punto dati inizia con un "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 } 
    }} 
]) 

Si noti che in tutti i casi il "dollaro $" prefisso voci sono le "variabili", riferendosi alla proprietà del documento. Questi sono "valori" per utilizzare un input sul lato destro. I "tasti" del lato sinistro devono essere specificati come una semplice chiave stringa. Nessuna variabile può essere utilizzata per nominare una chiave.

+1

Sì, questo funziona, ma in realtà conta tutti i valori nella raccolta, anziché il documento. Quello che sto cercando è l'equivalente del conteggio dei documenti secondari in ogni documento, incluso se ci sono 0. Modificherò il mio post originale per renderlo più chiaro. –

+0

@StevenHart Questo non era chiaro nella tua domanda. Ma si tratta semplicemente di includere l'id del documento nella chiave di raggruppamento. Guarda il cambiamento. –

+0

La seconda partita $ è necessaria dopo il $ unwinds? – TheGaff

Problemi correlati