Z góry, uważam, że odpowiedź @ benedolph to najlepsza praktyka i najlepszy scenariusz. Każda redukcja powinna idealnie zwrócić 1 wartość skalarną, aby kod był jak najprostszy.
Prawdą jest jednak, że należy wydać wiele zapytań, aby pobrać pełny zestaw wyników opisany w pytaniu. Jeśli nie masz możliwości równoległego uruchamiania zapytań lub bardzo ważne jest utrzymanie liczby zapytań, można zrobić to wszystko naraz.
Twoja funkcja mapy pozostanie dość prosta:
function (doc) {
emit([ doc.Period, doc.Region, doc.Category, doc.Product ], doc);
}
zmniejszyć funkcja jest, gdy robi się długa:
function (key, values, rereduce) {
// helper function to sum all the values of a specified field in an array of objects
function sumField(arr, field) {
return arr.reduce(function (prev, cur) {
return prev + cur[field];
}, 0);
}
// helper function to create an array of just a single property from an array of objects
// (this function came from underscore.js, at least it's name and concept)
function pluck(arr, field) {
return arr.map(function (item) {
return item[field];
});
}
// rereduce made this more challenging, and I could not thoroughly test this right now
// see the CouchDB wiki for more information
if (rereduce) {
// a rereduce handles transitionary values
// (so the "values" below are the results of previous reduce functions, not the map function)
return {
OrdersCount: sumField(values, "OrdersCount"),
MinRate: Math.min.apply(Math, pluck(values, "MinRate")),
MaxRate: Math.max.apply(Math, pluck(values, "MaxRate")),
TotQty: sumField(values, "TotQty"),
Amount: sumField(values, "Amount")
};
} else {
var rates = pluck(values, "Rate");
// This takes a group of documents and gives you the stats you were asking for
return {
OrdersCount: values.length,
MinRate: Math.min.apply(Math, rates),
MaxRate: Math.max.apply(Math, rates),
TotQty: sumField(values, "Qty"),
Amount: sumField(values, "Amount")
};
}
}
nie byłem w stanie przetestować „rereduce” oddział tego kodu na wszystko, będziesz musiał to zrobić na końcu. (ale to powinno zadziałać) Zobacz the wiki, aby uzyskać informacje o zmniejszaniu lub zmniejszaniu.
Funkcje pomocnicze, które dodałem u góry, sprawiły, że kod jest ogólnie krótszy i łatwiejszy do odczytania, w dużej mierze zależą one od mojego doświadczenia z Underscore.js. Nie można jednak włączać modułów CommonJS do funkcji zmniejszania, więc trzeba pisać ręcznie.
Ponownie, najlepszym scenariuszem jest, aby każde zagregowane pole otrzymało własną mapę/zmniejszyć indeks, ale jeśli to nie jest opcja dla ciebie, powyższy kod powinien dać ci to, co opisałeś tutaj w pytaniu .
Czy próbowałeś już czegoś? Prosty widok powinien działać dobrze. Niektóre przykładowe dokumenty pomogłyby komuś w udzieleniu bardziej szczegółowej/szczegółowej odpowiedzi. –
@ DominicBarnes Dostarczono kilku przykładowych dokumentów. –