MongoDB聚合与MeteorJS 中的分组问题 [英] MongoDB Aggregate & Grouping Issue in MeteorJS

查看:30
本文介绍了MongoDB聚合与MeteorJS 中的分组问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Using MongoDB in Meteor JS, how do you use Meteor Aggregate properly?

The intended result is to return grouped users by their userId and sum up a boolean field called "progressState" (true/false).

For example the document can have:

user 001 - true
user 001 - false
user 001 - true
user 003 - false
user 005 - true

but the intended result would be:

user 001: 2 true
user 003: 0 true
user 005: 1 true
etc..

My attempt gives the following error:

"exception: FieldPath field names may not start with '$'."

Here is my Meteor Code:

Meteor.publishComposite('completedLB', {
    find: function() {
        return userCompleted.aggregate([
            {
                $match: {
                    "progressState": "true"
                }
            },
            {
                $group: {
                    "_id": "$userId",
                    "count": {
                        "$sum": "$progressState"
                    }
                }
            },
            {
                $sort : {
                    "$progressState": -1
                }
            }
        ]);
    }
});

解决方案

If you are using the meteor hacks aggregate package to implement an .aggregate() command on your collection, then it will only just return an array in response. So you need to work that into a form of a published collection:

Meteor.publish("completedLB,function() {
    var self = this;

    var results = userCompleted.aggregate([
        { "$match": { "progressState": true } },
        { "$group": {
            "_id": "$userId",
             "progressState": { "$first": "$progressState" },
             "count": { "$sum": 1 }
        }},
        { "$sort": { "_id": 1 } }
    ]);

    _.each(results,function(result) {
        self.added("client_collection_name",Random.id(), {
            userId: result._id,
            progressState: result.progressState,
            count: result.count
        });
    });
    self.ready();
});

Or to include the false counts as your suggested output suggests itself:

        { "$group": {
            "_id": "$userId",
             "progressState": { "$first": true },
             "count": { "$sum": { "$cond": ["$progressState", 1,0] }
        }},
        { "$sort": { "_id": 1 } }

As the pipeline with a $cond evaluation to convert to numeric.

Where in the basic aggregation you are just "totalling" the matched results and of course the $sort refers to a field present in the output, which by your example would be the "userId" value now in the _id key from aggregation, but could also be "count" to order by the total count if wanted.

That part was producing the error, as $sort is a present field and not a field value with $ notation.

But of course to publish as a client accessible collection you need to replace the actual _id with something expected. So random id generation works here, as does the inclusion of the other fields.

For a bit more detail, and also an alternate to the "hacks" package that just works with a vanilla installation, there is also this answerby myself that has a complete listing as an example.

这篇关于MongoDB聚合与MeteorJS 中的分组问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆