От Meteor 0.6.5 API за колекция все още не поддържа заявки за агрегиране, защото няма (прост) начин да правите актуализации на живо за тях. Все пак можете да ги напишете сами и да ги направите достъпни в Meteor.publish
, въпреки че резултатът ще бъде статичен. Според мен все още е за предпочитане да се прави по този начин, защото можете да обедините множество агрегати и да използвате API за колекция от страна на клиента.
Meteor.publish("someAggregation", function (args) {
var sub = this;
// This works for Meteor 0.6.5
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
// Your arguments to Mongo's aggregation. Make these however you want.
var pipeline = [
{ $match: doSomethingWith(args) },
{ $group: {
_id: whatWeAreGroupingWith(args),
count: { $sum: 1 }
}}
];
db.collection("server_collection_name").aggregate(
pipeline,
// Need to wrap the callback so it gets called in a Fiber.
Meteor.bindEnvironment(
function(err, result) {
// Add each of the results to the subscription.
_.each(result, function(e) {
// Generate a random disposable id for aggregated documents
sub.added("client_collection_name", Random.id(), {
key: e._id.somethingOfInterest,
count: e.count
});
});
sub.ready();
},
function(error) {
Meteor._debug( "Error doing aggregation: " + error);
}
)
);
});
По-горе е пример за групиране/агрегиране на броя. Някои неща за отбелязване:
- Когато направите това, естествено ще правите агрегиране на
server_collection_name
и изпращане на резултатите към различна колекция, нареченаclient_collection_name
. - Този абонамент няма да бъде активен и вероятно ще бъде актуализиран всеки път, когато аргументите се променят, така че използваме наистина прост цикъл, който просто избутва всички резултати.
- Резултатите от агрегирането нямат Mongo ObjectID, така че генерираме някои свои собствени произволни.
- Обратното извикване към агрегирането трябва да бъде обвито във Fiber. Използвам
Meteor.bindEnvironment
тук, но може да се използва иFuture
за по-ниско ниво на контрол.
Ако започнете да комбинирате резултатите от публикации като тези, ще трябва внимателно да обмислите как произволно генерираните идентификатори влияят върху полето за сливане. Ясна реализация на това обаче е само стандартна заявка към база данни, с изключение на това, че е по-удобна за използване с API на Meteor от страна на клиента.
TL;DR версия :Почти всеки път, когато изтласквате данни от сървъра, publish
е за предпочитане пред method
.
За повече информация относно различните начини за извършване на агрегиране, вижте тази публикация .