[英]Merge and aggregate some fields of two or more collections with identical schema mongodb
我有一些具有相同架构的集合,我想对它们执行合并+聚合。 模式很简单,如下所示:
{ 'fr': 1, 'to': 1, 'wg': 213}
{ 'fr': 1, 'to': 2, 'wg': 53}
{ 'fr': 2, 'to': 2, 'wg': 5521}
以下代码可用于合并两个集合,但是我想知道是否有更快的解决方案和/或一个解决方案可以以类似的方式合并多个集合而无需创建嵌套调用:
var c = db.collection('first').find()
c.each(function(err, doc) {
if (err) throw err
if (doc == null) {
console.log('done')
return
}
db.collection('second').findOne({
'fr': doc['fr'],
'to': doc['to']
}, function(err, doc2) {
if (err) throw err
db.collection('my_results').save({
'fr': doc['fr'],
'to': doc['to'],
'wg': doc['wg'] + doc2['wg']
}, function(err) {
if (err) throw err
})
})
})
这里没有绝对的免费操作,因为您无法使用MongoDB进行联接。 但是您可以使用mapReduce及其某些功能来获得所需的输出。
因此,首先创建一个映射器:
var mapper = function () {
emit( { fr: this.fr, to: this.to }, this.wg )
};
然后是减速器:
var reducer = function (key,values) {
return Array.sum( values );
};
然后,运行mapReduce操作,将输出设置为另一个集合:
db.first.mapReduce(mapper,reducer,{ "out": { "reduce": "third" } })
注意此处的“ out”选项,本手册部分对此进行了说明 。 关键是,尽管控制台中可能会误导统计信息输出,但“ reduce”语句非常重要。 这样,当我们针对另一个集合运行相同的代码时:
db.second.mapReduce(mapper,reducer,{ "out": { "reduce": "third" } })
结果实际上发生的是,第一个操作的输出也传递到第二个操作的“减少”阶段。
最终结果是两个集合中所有具有相同键值的值都将被添加到“第三个”集合中:
{ "_id" : { "fr" : 1, "to" : 1 }, "value" : 426 }
{ "_id" : { "fr" : 1, "to" : 2 }, "value" : 106 }
{ "_id" : { "fr" : 2, "to" : 2 }, "value" : 11042 }
你可以让一个小票友如果你想你的fr
和to
是两个候选条件的任意顺序的独特组合,甚至跑过来这些结果另一个MapReduce的或聚合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.