Funkci snížení lze zavolat jednou pomocí klíče a všech odpovídajících hodnot (ale pouze v případě, že klíč obsahuje více hodnot – nebude-li pro klíč uvedena pouze 1 hodnota, nebude volán vůbec).
Může být také voláno vícekrát, pokaždé s klíčem a pouze podmnožinou odpovídajících hodnot a výsledky předchozího snížení pro tento klíč. Tento scénář se nazývá opětovné snížení . Abyste podpořili opětovné snížení, vaše funkce snížení by měla být idempotentní.
Funkce idempotentního snížení má dvě klíčové vlastnosti:
- vrácená hodnota funkce snížení by měla být ve stejném formátu jako hodnoty zabere to. Pokud tedy vaše funkce snížení přijímá pole řetězců, funkce by měla vrátit řetězec. Pokud přijímá objekty s několika vlastnostmi, měl by vrátit objekt obsahující stejné vlastnosti. To zajišťuje, že se funkce nezlomí, když je volána s výsledkem předchozího snížení.
- Nevytvářejte domněnky založené na počtu hodnot zabere to. Není zaručeno, že
values
parametr obsahuje vše hodnoty pro daný klíč. Tedy pomocívalues.length
ve výpočtech je velmi riskantní a je třeba se mu vyhnout.
Aktualizace: Dva níže uvedené kroky nejsou vyžadovány (nebo dokonce možné, nezkontroloval jsem) u novějších verzí MongoDB. Pokud zadáte výstupní kolekci v možnostech map-reduce, může nyní zvládnout tyto kroky:
{ out: { reduce: "tempResult" } }
Pokud je vaše funkce redukce idempotentní, neměli byste mít žádné problémy s redukcí map více kolekcí. Stačí znovu snížit výsledky každé sbírky:
Krok 1
Spusťte map-reduce pro každou požadovanou kolekci a uložte výsledky do jediné dočasné kolekce. Výsledky můžete uložit pomocí funkce finalizace:
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
Spusťte další map-reduce na dočasné kolekci pomocí stejné funkce snížení . Funkce mapy je jednoduchá funkce, která vybírá klíče a hodnoty z dočasné kolekce:
map = function () {
emit(this._id, this.value);
}
db.tempResult.mapReduce(map, reduce)
Toto druhé zmenšení mapy je v podstatě opětovné zmenšení a mělo by vám poskytnout výsledky, které potřebujete.