Mongodb 在mongo中对集合执行映射后聚合

Mongodb 在mongo中对集合执行映射后聚合,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我希望在将mongo db中的一些记录传递给聚合函数之前对它们进行操作。特别是,在对集合的某些属性执行求和之前,我需要对这些属性求和 最初无法在聚合查询中对属性进行求和,因为原始集合中的属性名称不同。例如,我从以下内容开始: { timestamp: 1346774400000, foo3: 12, foo45: 13, foo9: 2 }, { timestamp: 1346796000000, foo7: 33, foo2: 5 } { timestamp: 1346774400000,

我希望在将mongo db中的一些记录传递给聚合函数之前对它们进行操作。特别是,在对集合的某些属性执行求和之前,我需要对这些属性求和

最初无法在聚合查询中对属性进行求和,因为原始集合中的属性名称不同。例如,我从以下内容开始:

{ timestamp: 1346774400000, foo3: 12, foo45: 13, foo9: 2 }, 
{ timestamp: 1346796000000, foo7: 33, foo2: 5 }
{ timestamp: 1346774400000, foo_total: 27 }, 
{ timestamp: 1346796000000, foo_total: 38 } 
我需要修改每个文档,以汇总以“foo”开头的每个属性的值,然后汇总集合中每个文档的所有这些值

为此,我编写了一个映射操作,它将生成如下内容:

{ timestamp: 1346774400000, foo3: 12, foo45: 13, foo9: 2 }, 
{ timestamp: 1346796000000, foo7: 33, foo2: 5 }
{ timestamp: 1346774400000, foo_total: 27 }, 
{ timestamp: 1346796000000, foo_total: 38 } 
…但我无法对db.collection.map()的输出执行聚合函数


有没有办法做到这一点,或者有更好的方法做到这一点?我无法更改文档的现有结构,我希望避免执行map reduce操作,我不想将此操作转移到代码中。

如上所述,文档中不同键值的问题是聚合无法专门处理这些,至少在不知道所有可能的值和写一个很长的语句的情况下

当然,您当前的方法是在检索收集结果后处理收集结果,而实际上不会产生收集本身,因此无法将其传递给聚合

因此,最好的方法是将整个过程传递给mapReduce,逻辑相当简单。首先是地图绘制者:

var映射器=函数(){
var patt=/^([a-z | a-z]+)/;
var-total={};
for(在本例中为n){
如果((n==“时间戳”)| | n==“_id”)
继续;
var match=patt.exec(n)[0];
如果(!total.hasOwnProperty(匹配))
总[匹配]=0;
总计[匹配]+=此[n];
}
发射(空,总);
};
非常简单,这只是“询问”字段名,同时排除您知道不需要的任何字段名。在本例中,使用正则表达式匹配字段名中的第一个“alpha”字符。我允许字段可能是“foo16”、“bar32”、“baz12”,而这一切对操作都不重要。无论如何,有一些方法可以剥离您想要的字段部分

这些值在每个文档内部添加并发送到reducer,因为只有一个“key”,即
null

因此,在减速器中:

var reducer=函数(键、值){
var-reduced={};
values.forEach(函数(值){
for(var n值){
如果(!reduced.hasOwnProperty(n))
减少的[n]=0;
减少的[n]+=值[n];
}
});
回报减少;
};
这类似地循环发送的每个文档,并对找到的每个“字段”的结果求和,以生成结果:

{
“结果”:[
{
“_id”:空,
“价值”:{
“福”:65
}
}
],
“timeMillis”:7,
“计数”:{
“投入”:2,
“发射”:2,
“减少”:1,
“产出”:1
},
“好”:1,
}

仅基于您拥有的示例文档。

不太清楚您的最终结果是什么。事实上,您只是说想要“聚合”“但你并没有说你是如何聚合的,或者聚合的结果是什么。无论如何,如果您有不同的属性名称,如图所示,那么mapReduce可能会更好地处理整个操作。在不明确知道字段名称的情况下,无法操作聚合管道中的字段名称。或者没有暴力。我的错,我知道这可能有点难解开。我需要取每个foo_总值,并对所有文档求和。在提供的示例中,我的最终结果是27+38或65。谢谢Neil,这就是我最终所做的。不幸的是,我正在使用的文档有这种格式,这使得任务不像我希望的那样简单。这仍然比在代码中执行聚合要好,特别是考虑到我正在处理的数据的规模。