2013-02-28 16 views
7

È possibile fare riferimento ai valori dei singoli valori degli attributi nella pipeline di aggregazione MongoDB utilizzando l'operatore '$'. Ma come posso accedere (riferimento) all'intero documento?Riferimento dell'intero documento in MongoDB Aggregation Pipeline


UPDATE: Un esempio fornito per spiegare scenario.

Ecco un esempio di ciò che sto cercando di fare. Ho una collezione di tweet. E ogni tweet ha un membro 'cluster', che è un'indicazione di a quale cluster appartiene un particolare tweet.

{ 
    "_id" : "5803519429097792069", 
    "text" : "The following vehicles/owners have been prosecuted by issuing notice on the basis of photographs on dated... http://t.co/iic1Nn85W5", 
    "oldestts" : "2013-02-28 16:11:32.0", 
    "firstTweetTime" : "4 hours ", 
    "id" : "307161122191065089", 
    "isLoc" : true, 
    "powertweet" : true, 
    "city" : "new+delhi", 
    "latestts" : "2013-02-28 16:35:05.0", 
    "no" : 0, 
    "ts" : 1362081807.9693, 
    "clusters" : [ 
     { 
      "participationCoeff" : 1, 
      "clusterID" : "5803519429097792069" 
     } 
    ], 
    "username" : "dtptraffic", 
    "verbSet" : [ 
     "date", 
     "follow", 
     "prosecute", 
     "have", 
     "be" 
    ], 
    "timestamp" : "4 hours ", 
    "entitySet" : [ ], 
    "subCats" : { 
     "Generic" : [ ] 
    }, 
    "lang" : "en", 
    "fns" : 18.35967, 
    "url" : "url|109|131|http://fb.me/2CeaI7Vtr", 
    "cat" : [ 
     "Generic" 
    ], 
    "order" : 7 
} 

Dal momento che, ci sono alcuni paio di centinaia di migliaia di tweet nella mia collezione, voglio gruppo tutti i tweet di 'clusters.clusterID'. Fondamentalmente, vorrei scrivere una query come segue:

db.tweets.aggregate (
{ $group : { _id : '$clusters.clusterID', 'members' : {$addToSet : <????> } } } 
) 

voglio accedere al documento attualmente elaborazioni ed è dove ho messo nella query precedente. Qualcuno sa come farlo?

+1

avete un esempio di ciò che si sta cercando di fare? – RickyA

+1

in poche parole - no, non c'è modo di farlo (ci sarebbe se tu sapessi tutti i nomi delle chiavi, ma è improbabile che sia di aiuto). –

+0

si potrebbe fare questo in agg framework se si è disposti ad accontentarsi di un set fisso di campi del documento originale. –

risposta

-1

Penso che MapReduce più utile per questa attività.

Come scritto nei commenti di Asya Kamsky, il mio esempio non è corretto per mongodb, si prega di utilizzare official docs per mongoDB.

+0

hai ragione che la mappa/ridurre può farlo, ma quello che hai dato qui non funzionerà. La tua mappa è leggermente sbagliata e la tua funzione di riduzione sembra mancare del tutto. –

+0

non è come funziona map/reduce. La funzione di riduzione deve restituire lo stesso formato emesso dalla funzione mappa, e può anche essere chiamato più di una volta. Il tuo test potrebbe aver dato la risposta "giusta" per qualche piccolo test set, ma non funzionerà correttamente sui dati reali. –

+1

vedere la pagina dei documenti per mapReduce. http://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/# requirements-per-the-reduce-function elenca entrambi questi fatti (oltre al fatto che la riduzione non verrà chiamata per le chiavi mappate che si verificano una sola volta) –

2

Non ci sono attualmente meccanismo per accedere al documento completo nel quadro di aggregazione, se avevi bisogno di solo un sottoinsieme di campi, si potrebbe fare:

db.tweets.aggregate([ {$group: { _id: '$clusters.clusterID', 
            members: {$addToSet : 
             { user: "$user", 
             text: "$text", // etc for subset 
                 // of fields you want 
             } 
            } 
           } 
         } ]) 

Non dimenticare con poche centinaia di migliaia tweets, aggregando il documento completo ti porterà al limite di 16 MB per il documento dei risultati del framework di aggregazione restituito.

È possibile farlo attraverso MapReduce in questo modo:

var m = function() { 
    emit(this.clusters.clustersID, {members:[this]}); 
} 

var r = function(k,v) { 
    res = {members: [ ] }; 
    v.forEach(function (val) { 
    res.members = val.members.concat(res.members); 
    }); 
    return res; 
} 

db.tweets.mapReduce(m, r, {out:"output"}); 
+0

Ho avuto lo stesso problema e BatScream ha offerto la seguente soluzione. http://stackoverflow.com/questions/34404834/how-to-group-and-select-document-corresponding-to-max-within-each-group-in-mongo?noredirect=1#comment56552218_34404834. Ha suggerito di accedere al documento completo tramite $$ ROOT – user1700890

+0

$$ ROOT è stato introdotto in 2.6 e non era disponibile al momento di questa domanda/risposta. https://jira.mongodb.org/browse/SERVER-9840 –

9

Nella documentazione ho trovato che l'espressione $$ROOT risolve questo problema.

Dal DOC: http://docs.mongodb.org/manual/reference/operator/aggregation/group/#group-documents-by-author

+1

questa domanda è stata posta quando MongoDB 2.2 era aggiornato - $$ ROOT è stato aggiunto nella versione 2.6 (inizio 2014) –

+1

forse potresti rispondere [questa mia domanda] (http://stackoverflow.com/questions/39288087/mongodb-collection-with-different-language-texts-select-localized-texts). Il problema è che mi piacerebbe ottenere il documento stesso, non come documento secondario, tipo di '{$ group: $$ ROOT}' che non è possibile, e per il momento può essere solo un documento secondario: '{$ gruppo: {_id: '$$ ROOT'}} ' – Miquel

+0

Come eseguire questa operazione quando si utilizza prima una proiezione? – Dane411

Problemi correlati