Od wersji 1.0.4 Meteor:
Możesz więc wywołać collection.rawCollection()
aby uzyskać podstawowy obiekt kolekcji:
var rawCollection = Orders.rawCollection();
Ta rawCollection
ma metodę group
która jest odpowiednikiem group
w powłoce MongoDB. Bazowy interfejs API węzła jest jednak asynchroniczny, więc będziesz chciał jakoś przekonwertować go na funkcję synchroniczną. Nie możemy użyć Meteor.wrapAsync
bezpośrednio od group
przyjmuje argumenty funkcji, które nie są podstawowym wywołaniem zwrotnym, więc obejdziemy to za pomocą opakowania:
function ordersGroup(/* arguments */) {
var args = _.toArray(arguments);
return Meteor.wrapAsync(function (callback) {
rawCollection.group.apply(rawCollection, args.concat([callback]));
})();
}
Wewnątrz swojej metody możesz wywołać ordersGroup
tak jak db.orders.group
w powłoce Mongo. Jednak argumenty są przekazywane osobno, a nie w obiekcie:
ordersGroup(keys, condition, initial, reduce[, finalize[, command[, options]]])
Więcej informacji znajdziesz w tej dokumentacji
(choć zauważ, że callback
parametr powinien zostać pominięty, ponieważ zajmuje się tym nasze zawijanie asynchroniczne).
Musisz więc przekazać je osobno:
var result = ordersGroup(
// keys
function(doc) {
return { year: doc.createdAt.toISOString().substring(0, 4) };
},
// condition
{createdAt: {$lt: new Date("2015-12-31"), $gt: new Date("2015-01-01")}},
// initial
{months: {}},
// reduce
function(order, result) {
var month = order.createdAt.getMonth()+1,
date = order.createdAt.getDate();
month = result.months[month] || (result.months[month] = {});
date = month[date] || (month[date] = []);
date.push(order);
}
);
Oczywiście działa to tylko na serwerze, więc upewnij się, że twoja metoda jest tylko w kodzie serwera (najlepiej w server
podkatalogu lub wewnątrz if (Meteor.isServer)
).