在Meteor JS中使用MongoDB,如何正确使用Meteor Aggregate?
预期结果是按 userId 返回分组的用户,并对名为“progressState”(true/false)的 bool 字段求和。
例如文档可以有:
user 001 - true
user 001 - false
user 001 - true
user 003 - false
user 005 - true
但预期的结果是:
user 001: 2 true
user 003: 0 true
user 005: 1 true
etc..
我的尝试出现以下错误:
"exception: FieldPath field names may not start with '$'."
这是我的 meteor 代码:
Meteor.publishComposite('completedLB', {
find: function() {
return userCompleted.aggregate([
{
$match: {
"progressState": "true"
}
},
{
$group: {
"_id": "$userId",
"count": {
"$sum": "$progressState"
}
}
},
{
$sort : {
"$progressState": -1
}
}
]);
}
});
最佳答案
如果您使用 meteor hacks aggregate包来在您的集合上实现 .aggregate()
命令,那么它只会返回一个数组作为响应。因此,您需要将其转化为已发布集合的形式:
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();
});
或者按照您建议的输出本身的建议包含 false
计数:
{ "$group": {
"_id": "$userId",
"progressState": { "$first": true },
"count": { "$sum": { "$cond": ["$progressState", 1,0] }
}},
{ "$sort": { "_id": 1 } }
作为具有 $cond
的管道评估转换为数字。
在基本聚合中,您只是“总计”匹配的结果,当然还有 $sort
指输出中存在的字段,根据您的示例,该字段现在是聚合中 _id
键中的“userId”值,但如果需要,也可以是“count”以按总计数排序。
该部分产生了错误,因为 $sort
是一个当前字段,而不是带有 $
表示法的字段值。
但是,当然要发布为客户端可访问的集合,您需要将实际的 _id
替换为预期的内容。因此,随机 ID 生成在这里起作用,其他字段的包含也是如此。
要了解更多详细信息,以及仅适用于普通安装的“hacks”包的替代方案,还有 this answer我自己有一个完整的列表作为示例。
关于Meteor JS 中的 MongoDB 聚合和分组问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31823761/