2013-02-28 11 views
7

Mogę odwoływać się do wartości poszczególnych wartości atrybutów w potoku agregacji MongoDB za pomocą operatora "$". Ale jak mam uzyskać dostęp do (odniesienia) całego dokumentu?Odwoływanie się do całego dokumentu w Pipeline agregacji MongoDB


UPDATE: Przykład warunkiem wyjaśnić scenariusz.

Oto przykład tego, co próbuję zrobić. Mam zbiór tweetów. I każdy tweet ma element "klastrów", co jest wskazówką do jakiego klastra należy dany 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 
} 

Ponieważ istnieją pewne kilkaset tysięcy tweetów w mojej kolekcji, chcę grupy wszystkie tweets przez „clusters.clusterID”. Zasadniczo chciałbym napisać zapytanie jak następuje:

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

Chcę uzyskać dostęp do dokumentu obecnie przetwarzanie i odwoływać gdzie mam umieścić w powyższym zapytaniu. Czy ktoś wie, jak to zrobić?

+1

masz przykład tego, co próbujesz zrobić? – RickyA

+1

w pigułce - nie, nie ma sposobu, aby to zrobić (nie byłoby, gdybyś znał wszystkie kluczowe nazwy, ale to raczej nie będzie pomocne). –

+0

można to zrobić w ramach ag, jeśli chcesz udzielić rozliczenia dla ustalonego zestawu pól oryginalnego dokumentu. –

Odpowiedz

-1

Myślę, że MapReduce jest bardziej przydatna w tym zadaniu.

Jak napisano w komentarzach Asy Kamsky, mój przykład jest niepoprawny dla mongodb, proszę użyć official docs dla mongoDB.

+0

masz rację, że map/reduce to potrafi, ale to, co tu dałeś, nie zadziała. Twoja mapa jest nieco błędna, a funkcja redukcji wydaje się być całkowicie nieobecna. –

+0

to nie działa w trybie mapowania/zmniejszania. Funkcja zmniejszania musi zwracać ten sam format, który emituje funkcja mapy, a także może być wywoływana więcej niż raz. Twój test mógł dać "prawidłową" odpowiedź dla jakiegoś małego zestawu testowego, ale nie zadziała poprawnie na prawdziwych danych. –

+1

zobacz stronę dokumentacji dla mapReduce. http://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/# requirements-for-the-reduction-function wymienia oba te fakty (oraz fakt, że redukcja nie będzie w ogóle wywoływana dla zamapowanych kluczy, które występują tylko raz). –

2

Obecnie nie ma mechanizmu dostęp do pełnego dokumentu w ramach agregacji, jeśli potrzebne tylko podzbiór pól, można zrobić:

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

Nie zapomnij z kilkuset tysięcy tweetów, sumując pełny dokument spowoduje przejście do limitu 16 MB dla zwróconego dokumentu wynikowego agregacji.

Można to zrobić poprzez MapReduce tak:

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

Miałem ten sam problem i BatScream zaoferował następujące rozwiązanie. http://stackoverflow.com/questions/34404834/how-to-group-and-select-document-corresponding-to-max-within-each-group-in-mongo?noredirect=1#comment56552218_34404834. Zasugerował dostęp do pełnego dokumentu za pośrednictwem $$ ROOT – user1700890

+0

$$ ROOT został wprowadzony w wersji 2.6 i nie był dostępny w czasie tego pytania/odpowiedzi. https://jira.mongodb.org/browse/SERVER-9840 –

9

W dokumentacji znalazłem, że wyrażenie $$ROOT rozwiązuje ten problem.

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

+1

to pytanie zadano, gdy MongoDB 2.2 był aktualny - $$ ROOT został dodany w wersji 2.6 (początek 2014) –

+1

może mógłbyś odpowiedzieć [to moje pytanie] (http://stackoverflow.com/questions/39288087/mongodb-collection-with-different-language-texts-select-localized-texts). Problem polega na tym, że chciałbym uzyskać sam dokument, a nie subdokument, rodzaj '{$ group: $$ ROOT}', który nie jest możliwy, i na razie może być po prostu jako poddokumentem: '{$ group: {_id: '$$ ROOT'}} ' – Miquel

+0

Jak to działa, gdy najpierw używa się projekcji? – Dane411