Агрегация с помощью meteorhacks:aggregate (зачем мне вообще использовать $out)?

Это существенное редактирование этого вопроса, так как я изменил публикацию на метод и сузил область вопроса.

Я использую meteorhacks:aggregate для расчета и публикации среднего и медианного значения данных об оценке компании для выбранной пользователем серии компаний. Выборки сохраняются в коллекции оценок для справки, а данные для агрегирования поступают из коллекции компаний.

Приведенный ниже код отлично подходит для одноразового использования (хотя он и не является реактивным). Однако пользователи будут повторно запускать эту агрегацию в течение тысяч valuationIdс. Поскольку $out сначала очистит новую коллекцию перед вставкой новых результатов, я не могу использовать это здесь, мне нужно сохранить результаты каждого экземпляра. Я не понимаю, зачем использовать $out.

Есть ли способ просто добавить обновление существующего документа оценки с результатами агрегирования, а затем подписаться на этот документ?

сервер/методы

Meteor.methods({
    valuationAggregate: function(valuationId, valuationSelections) {
        //Aggregate and publish average of company valuation data for a user-selected series of companies./
        //Selections are saved in Valuations collection for reference and data for aggregation comes from Companies collection.//
        check(valuationId, String);
        check(valuationSelections, Array);
        var pipelineSelections = [
            //Match documents in Companies collection where the 'ticker' value was selected by the user.//
            {$match: {ticker: {$in: valuationSelections}}},
            {
                $group: {
                    _id: null,
                    avgEvRevenueLtm: {$avg: {$divide: ["$capTable.enterpriseValue", "$financial.ltm.revenue"]}},
                    avgEvRevenueFy1: {$avg: {$divide: ["$capTable.enterpriseValue", "$financial.fy1.revenue"]}},
                    avgEvRevenueFy2: {$avg: {$divide: ["$capTable.enterpriseValue", "$financial.fy2.revenue"]}},
                    avgEvEbitdaLtm: {$avg: {$divide: ["$capTable.enterpriseValue", "$financial.ltm.ebitda"]}},
                    //more//
                }
            },
            {
                $project: {
                    _id: 0,
                    valuationId: {$literal: valuationId},
                    avgEvRevenueLtm: 1,
                    avgEvRevenueFy1: 1,
                    avgEvRevenueFy2: 1,
                    avgEvEbitdaLtm: 1,
                    //more//
                }
            }
        ];

        var results = Companies.aggregate(pipelineSelections);
        console.log(results);
        }
});

Приведенный выше код работает при просмотре результатов на сервере. В моем терминале я вижу:

I20150926-23:50:27.766(-4)? [ { avgEvRevenueLtm: 3.988137239679733,
I20150926-23:50:27.767(-4)?     avgEvRevenueFy1: 3.8159564713187155,
I20150926-23:50:27.768(-4)?     avgEvRevenueFy2: 3.50111769838031,
I20150926-23:50:27.768(-4)?     avgEvEbitdaLtm: 11.176476895728268,
//more//
I20150926-23:50:27.772(-4)?     valuationId: 'Qg4EwpfJ5uPXyxe62' } ]

person Bren    schedule 22.09.2015    source источник


Ответы (1)


Я смог решить это следующим образом. Необходимо добавить forEach для раскрутки массива так же, как $out.

библиотека/коллекции

ValuationResults = new Mongo.Collection('valuationResults');

сервер/методы

    var results = Companies.aggregate(pipelineSelections);
    results.forEach(function(valuationResults) {
        ValuationResults.update({'result.valuationId': valuationId}, {result:valuationResults}, {upsert: true});
    });
    console.log(ValuationResults.find({'result.valuationId': valuationId}).fetch());
}
});
person Bren    schedule 28.09.2015