【问题标题】:Shared mapreduce results collection in MongoDBMongoDB 中的共享 mapreduce 结果集合
【发布时间】:2012-06-29 23:43:48
【问题描述】:

我有几个正在运行 mapreduce 的 Mongoid 模型,我想将统一的结果存储在单个 daily_stats 集合中。我的 map & reduce 函数适用于所有 3 个模型,但即使通过 collection.mapreduce(map, reduce, {:out => "daily_stats", :raw => true}) 输出,后续 map reduce 操作的结果也会覆盖以前的结果,即使它们没有重叠键:

{'_id': "2012-06-01", 'values': {photos: 10}}
{'_id': "2012-06-02", 'values': {photos: 10}}

photos 的值在后续传递返回时被丢弃:

{'_id': "2012-06-01", 'values': {comments: 1}}
{'_id': "2012-06-02", 'values': {comments: 6}}

我也尝试与collection.mapreduce(map, reduce, {:out => {:merge => "daily_stats"}, :raw => true}) 合并,但这似乎也不起作用。

有什么想法吗?

更新

每个模型的 map 和 reduce 函数都是这样的:

地图:

function() {
    day = Date.UTC(this.created_at.getFullYear(), this.created_at.getMonth(), this.created_at.getDate());
    emit(day, {users: 1});
  };

减少: 功能(键,值){ var users_added_count = 0;

    values.forEach(function(v) {
      users_added_count += parseInt(v['users']) || 0;
    });

    return {users: users_added_count};
  }

以下是关于生成的架构的一些额外信息:

{ "_id" : 1337040000000,
 "value" : {
  "apartments" : 280,
  "price" : 1003653,
  "photos" : 83,
  "comments" : 0 } 
 }

【问题讨论】:

  • 有什么原因你没有和/或不能运行一次 map reduce 并发出一个文档,即:emit(day, {users: 1}, {photos: 1}, {cmets: 1})?
  • 哦,我明白了。您最初拥有三个独立的集合 - 一个用于用户、照片和 cmets?我将编写一个示例来说明合并数据的方法。
  • 或者来自“结果模式”的文档是您的输入数据模型?抱歉,澄清一下,您能否提供更多数据示例?

标签: mongodb mapreduce mongoid analytics


【解决方案1】:

如果您查看有关 map reduce 的 MongoDB 文档 (http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions),您会看到默认情况下,MR 输出集合会替换任何现有的同名的集合。 “合并”将新数据添加到旧的输出集合中,但使用相同的键覆盖文档。

看起来你的关键是日期?如果

{'_id': "2012-06-01", 'values': {photos: 10}}

{'_id': "2012-06-01", 'values': {comments: 1}}

具有相同的密钥,当您运行 MR 时,第二个文档将替换第一个文档。您要么需要指定一个更唯一的键,要么需要有多个输出集合(可能一个用于照片,一个用于 cmets?)。

【讨论】:

  • 正确,关键是日期。没有办法用相同的键合并项目吗?有点像 $addToSet 对数组字段的作用?
  • 由于每个文档都必须有一个唯一的_id字段(以便在文档上创建唯一索引并跟踪文档的位置),因此无法合并具有相同键的文档;但是,我认为您的问题有一个解决方案,涉及 map reduce 中的 finalize 函数。如果您提供有关您的 MR 函数和数据架构的其他信息,我可能会提供帮助。
  • 当然,我为用户添加了我的地图和减少。其他型号几乎相同。
【解决方案2】:

您可以使用哈希键发出,以使其在您的模型中独一无二

emit({day: day, type: '<model class name>'}, 1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多