Mongodb聚合/映射减少许多集合中的值

Mongodb聚合/映射减少许多集合中的值,mongodb,aggregation-framework,spring-data-mongodb,Mongodb,Aggregation Framework,Spring Data Mongodb,我有大约3000万份文件,如: { "_id" : { "municipality" : "Stockholm", "keyword" : "hotel" }, "total" : 2 } 在12个月的基础上收集。现在,我需要将这些值汇总到全年的集合中。关于如何在一个集合中进行聚合,有很多例子,但我不确定其中许多集合如何开始聚合。我应该从一些mapreduce emit函数开始吗?我想您可能可以使用该命令获取集合名称数组,然后在循环中迭代,使用该方法计算每个集合的聚合 为了说

我有大约3000万份文件,如:

{
 "_id" : {
    "municipality" : "Stockholm",
    "keyword" : "hotel"
},
"total" : 2
}

在12个月的基础上收集。现在,我需要将这些值汇总到全年的集合中。关于如何在一个集合中进行聚合,有很多例子,但我不确定其中许多集合如何开始聚合。我应该从一些mapreduce emit函数开始吗?

我想您可能可以使用该命令获取集合名称数组,然后在循环中迭代,使用该方法计算每个集合的聚合

为了说明这一点,假设在测试数据库中有以下集合和相应的文档:

use test;
db.jan_stats.insert([
    {
         "_id" : {
            "municipality" : "Stockholm",
            "keyword" : "hotel"
        },
        "total" : 2
    },
    {
         "_id" : {
            "municipality" : "Malmö",
            "keyword" : "school"
        },
        "total" : 5
    }
]);
db.feb_stats.insert([
    {
         "_id" : {
            "municipality" : "Stockholm",
            "keyword" : "hotel"
        },
        "total" : 6
    },
    {
         "_id" : {
            "municipality" : "Malmö",
            "keyword" : "school"
        },
        "total" : 4
    }
]);
然后,您可以在mongo shell中尝试上述逻辑,如下所示:

connecting to: test
> var collections = db.getCollectionNames(),
...     annual_total = 0;
> collections.forEach(function(name){
...     var res = db.getCollection(name).aggregate([
...         {
...             "$group": {
...                 "_id": null,
...                 "total": { "$sum": "$total" }
...             }
...         }
...     ]).toArray();
...     annual_total += res[0].total;
... });
> print(annual_total);
17
> 
如果实际收集数量为12,即每个月,上述内容当然会为您提供正确的年度总数

在性能方面,您需要进行适当的优化,以便上述聚合更快地工作。不太清楚这与Map Reduce操作相比如何,但我相信如果您只在total字段上进行聚合,然后使用来提高性能,那么聚合方法会相对更快