首先,是背景。我曾经有一个集合logs,并使用map/reduce来生成各种报告。这些报告中的大多数都是基于一天内的数据,所以我总是有一个条件d: SOME_DATE。当logs集合变得非常大时,插入变得非常慢(比我们监控的应用程序生成日志还要慢),即使在删除了大量索引之后也是如此。因此,我们决定将每天的数据放在一个单独的集合中-- logs_YYYY-mm-dd --这样索引就会更小,甚至不需要日期索引。这很酷,因为大多数报告(例如map/reduce)都是基于每日数据的。然而,我们有一份需要涵盖多天的报告。
现在问题来了。有没有办法在多个集合上运行map/reduce (或者更准确地说,map),就好像它只是一个集合一样?
发布于 2010-10-01 17:05:28
一个reduce函数可以被调用一次,使用一个键和所有相应的值(但只有当键有多个值时才会调用-如果键只有一个值,则根本不会调用)。
它也可以被多次调用,每次都使用一个键,并且只使用相应值的一个缩减子集,以及该键的前一个结果。这种情况称为re-reduce。为了支持re- reduce,你的reduce函数应该是idempotent。
幂等化简函数有两个关键特性:
values参数包含给定键的所有值。因此,在计算中使用values.length是非常有风险的,应该避免使用。更新:在最新的MongoDB版本中,以下两个步骤不是必需的(甚至是可能的,我还没有检查过)。现在,如果您在map-reduce options中指定输出集合,则它可以为您处理这些步骤
{ out: { reduce: "tempResult" } }如果reduce函数是幂等函数,那么减少多个集合的map应该不会有任何问题。只需重新减少每个集合的结果:
第一步
在每个必需的集合上运行map-reduce,并将结果保存在一个临时集合中。您可以使用finalize function存储结果
finalize = function (key, value) {
db.tempResult.save({ _id: key, value: value });
}
db.someCollection.mapReduce(map, reduce, { finalize: finalize })
db.anotherCollection.mapReduce(map, reduce, { finalize: finalize })第二步
使用相同的reduce函数在临时集合上运行另一个map-reduce。map函数是一个简单的函数,它从临时集合中选择键和值:
map = function () {
emit(this._id, this.value);
}
db.tempResult.mapReduce(map, reduce)第二个map-reduce基本上是一个re-reduce,应该会给出您需要的结果。
发布于 2017-12-02 05:26:26
我使用了map-reduce方法。下面是一个例子。
var mapemployee = function () {
emit(this.jobid,this.Name);};
var mapdesignation = function () {
emit(this.jobid, this.Designation);};
var reduceF = function(key, values) {
var outs = {Name:null,Designation: null};
values.forEach(function(v){
if(outs.Name ==null){
outs.Name = v.Name }
if(outs.Name ==null){
outs.Nesignation = v.Designation}
});
return outs;
};
result = db.employee.mapReduce(mapemployee, reduceF, {out: {reduce: 'output'}});
result = db.designation.mapReduce(mapdesignation,reduceF, {out: {reduce: 'output'}});后效:http://www.itgo.me/a/x3559868501286872152/mongodb-join-two-collections
https://stackoverflow.com/questions/3837394
复制相似问题