首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在多个集合上进行MongoDB映射/还原?

在多个集合上进行MongoDB映射/还原?
EN

Stack Overflow用户
提问于 2010-10-01 16:01:11
回答 2查看 17.3K关注 0票数 16

首先,是背景。我曾经有一个集合logs,并使用map/reduce来生成各种报告。这些报告中的大多数都是基于一天内的数据,所以我总是有一个条件d: SOME_DATE。当logs集合变得非常大时,插入变得非常慢(比我们监控的应用程序生成日志还要慢),即使在删除了大量索引之后也是如此。因此,我们决定将每天的数据放在一个单独的集合中-- logs_YYYY-mm-dd --这样索引就会更小,甚至不需要日期索引。这很酷,因为大多数报告(例如map/reduce)都是基于每日数据的。然而,我们有一份需要涵盖多天的报告。

现在问题来了。有没有办法在多个集合上运行map/reduce (或者更准确地说,map),就好像它只是一个集合一样?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-01 17:05:28

一个reduce函数可以被调用一次,使用一个键和所有相应的值(但只有当键有多个值时才会调用-如果键只有一个值,则根本不会调用)。

它也可以被多次调用,每次都使用一个键,并且只使用相应值的一个缩减子集,以及该键的前一个结果。这种情况称为re-reduce。为了支持re- reduce,你的reduce函数应该是idempotent

幂等化简函数有两个关键特性:

  • reduce函数的返回值的格式应该与它接受的值的格式相同。因此,如果reduce函数接受字符串数组,则该函数应返回一个字符串。如果它接受具有多个属性的对象,它应该返回一个包含这些相同属性的对象。这确保了函数在使用前一个reduce.
  • Don't的结果调用时不会中断,并根据它接受的值的数量进行假设。不能保证values参数包含给定键的所有值。因此,在计算中使用values.length是非常有风险的,应该避免使用。

更新:在最新的MongoDB版本中,以下两个步骤不是必需的(甚至是可能的,我还没有检查过)。现在,如果您在map-reduce options中指定输出集合,则它可以为您处理这些步骤

代码语言:javascript
复制
{ out: { reduce: "tempResult" } }

如果reduce函数是幂等函数,那么减少多个集合的map应该不会有任何问题。只需重新减少每个集合的结果:

第一步

在每个必需的集合上运行map-reduce,并将结果保存在一个临时集合中。您可以使用finalize function存储结果

代码语言:javascript
复制
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函数是一个简单的函数,它从临时集合中选择键和值:

代码语言:javascript
复制
map = function () {
  emit(this._id, this.value);
}

db.tempResult.mapReduce(map, reduce)

第二个map-reduce基本上是一个re-reduce,应该会给出您需要的结果。

票数 35
EN

Stack Overflow用户

发布于 2017-12-02 05:26:26

我使用了map-reduce方法。下面是一个例子。

代码语言:javascript
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3837394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档