MongoDB map / reduce over multiple collections?

Najpierw tło. Kiedyś miałem kolekcję logs i używałem map/reduce do generowania różnych raportów. Większość tych raportów była oparta na danych z jednego dnia, więc zawsze miałem warunek d: SOME_DATE. Gdy kolekcja logs rozrosła się ogromnie, wstawianie stało się niezwykle powolne( wolniej niż monitorowana przez nas aplikacja generowała logi), nawet po zrzuceniu dużej ilości indeksów. Postanowiliśmy więc mieć dane każdego dnia w osobnym zbiorze - logs_YYYY-mm-dd - w ten sposób indeksy są mniejsze, i nie potrzebujemy nawet indeksu daty. Jest to fajne, ponieważ większość raportów (a więc map/reduce) są na danych dziennych. Mamy jednak raport, w którym musimy uwzględnić kilka dni.

A teraz pytanie. Czy istnieje sposób, aby uruchomić mapę / zmniejszyć (a dokładniej mapę) na wielu kolekcjach, tak jakby była tylko jedna?
Author: ibz, 2010-10-01

2 answers

Funkcja reduce może być wywołana raz, z kluczem i wszystkimi odpowiadającymi jej wartościami (ale tylko wtedy, gdy dla klucza jest wiele wartości - nie zostanie wywołana w ogóle, Jeśli dla klucza jest tylko 1 wartość).

Może być również wywołany wiele razy, za każdym razem z kluczem i tylko podzbiorem odpowiednich wartości , a poprzednie wyniki redukcji dla tego klucza. Ten scenariusz nazywa się re-reduce . Aby wspierać ponowne redukcje, twoja funkcja redukcji powinna być idempotent .

Istnieją dwie kluczowe cechy w funkcji redukcji idempotentnej:

  • wartość zwracana funkcji reduce powinna być w tym samym formacie, w którym przyjmuje się wartości . Tak więc, jeśli funkcja reduce akceptuje tablicę łańcuchów, funkcja powinna zwrócić łańcuch. Jeśli akceptuje obiekty z kilkoma właściwościami, powinien zwrócić obiekt zawierający te same właściwości. Zapewnia to, że funkcja nie pęknie, gdy zostanie wywołana w wyniku poprzedniego zmniejszenia.
  • nie przyjmuj założeń na podstawie liczby wartości . Nie jest gwarantowane, że parametr values zawiera wszystkie wartości dla danego klucza. Zatem użycie values.length w obliczeniach jest bardzo ryzykowne i należy go unikać.

Aktualizacja: dwa poniższe kroki nie są wymagane (a nawet możliwe, nie sprawdzałem) w nowszych wydaniach MongoDB. Może teraz obsłużyć te kroki, jeśli określisz zbiór wyjściowy na mapie-zmniejsz opcje :

{ out: { reduce: "tempResult" } }

Jeśli funkcja reduce jest idempotentna, nie powinieneś mieć żadnych problemów z redukcją wielu kolekcji. Po prostu zredukuj wyniki każdej kolekcji:

Krok 1

Uruchom map-reduce na każdej wymaganej kolekcji i zapisz wyniki w jednej, tymczasowej kolekcji. Możesz zapisać wyniki za pomocą finalizuj funkcję :

finalize = function (key, value) {
  db.tempResult.save({ _id: key, value: value });
}

db.someCollection.mapReduce(map, reduce, { finalize: finalize })
db.anotherCollection.mapReduce(map, reduce, { finalize: finalize })

Krok 2

Uruchom kolejną mapę-zmniejsz na zbiór tymczasowy, przy użyciu tej samej funkcji reduce . Funkcja map jest prostą funkcją, która wybiera klucze i wartości z kolekcji tymczasowej:

map = function () {
  emit(this._id, this.value);
}

db.tempResult.mapReduce(map, reduce)

Ta druga mapa-reduce jest w zasadzie ponowną redukcją i powinna dać ci potrzebne wyniki.

 35
Author: Niels van der Rest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-15 14:58:34

Zastosowałem metodę map-reduce. oto przykład.

var mapemployee = function () {
    emit(this.jobid,this.Name);};

var mapdesignation = function () {
    emit(this.jobid, this.Designation);};

var reduceF = function(key, values) {
    var outs = {Name:null,Designation: null};
    values.forEach(function(v){
    if(outs.Name ==null){
   outs.Name = v.Name }
   if(outs.Name ==null){
    outs.Nesignation = v.Designation}                    
     });
    return outs;
};

result = db.employee.mapReduce(mapemployee, reduceF, {out: {reduce: 'output'}});
result = db.designation.mapReduce(mapdesignation,reduceF, {out: {reduce: 'output'}});

Referencja: http://www.itgo.me/a/x3559868501286872152/mongodb-join-two-collections

 1
Author: Lasith Niroshan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 21:26:25