【问题标题】:MongoDB mapReduce: Emit a DBRef oid as keyMongoDB mapReduce:发出一个 DBRef oid 作为键
【发布时间】:2014-02-23 11:03:00
【问题描述】:

我需要维护一个将数据存储在 MongoDB 中的应用程序,而且我对 mapReduce 语法很流利。

我想做一个 mapReduce 操作,其中发出的键是 DBRefID,而不是它的值。我从MongoDB documentation 清楚地了解到,出于并行性原因,一个人不能也不能访问数据库。

所以我的收藏文档是这样的:

{
  _id: "66f072b8-2422-4022-826b-b20b832a1ee6",
  _class: "com.foo.bar",
  foo_bar: 1,
  user: {
    "$dbref": {
      namespace: "user",
      oid: "6cd0dac5-a511-48b1-b437-318ad74061a5"
    }
  }
}

当前的 mapReduce 是这样的:

db.myCollection.mapReduce(
  function () {
      if (this.foo_bar > 0) {
          emit(this.user, this.foo_bar);
      }
  },
  function (key, values) {
      var sum = 0;
      for (var i = 0; i < values.length; i++) {
          sum += values[i];
      }
      return sum;
  },

  {
    "out" : { "inline" : 1} 
  }
)

有很多文档,AWS 和 MongoHQ 之间的加载需要很长时间。我希望能够使用 user$id 作为键,而不是 DBRef 的文档。

我已经测试了以下但没有成功:

  1. emit(this.user.id, this.foo_bar);
  2. emit(this.user.oid, this.foo_bar);
  3. emit(this.user._id, this.foo_bar);
  4. emit(this.user.dbref.id,this.foo_bar);
  5. emit(this.user.dbref.oid, this.foo_bar);
  6. emit(this.user.dbref._id, this.foo_bar);
  7. emit(this.user['$dbref'].oid, this.foo_bar); (根据 cmets 中的 Sammaye 建议)

正确的语法是什么?

【问题讨论】:

  • this.user['$dbref'].oid
  • 不。 Mongo 给出:Thu Jan 30 23:22:52.584 map reduce failed:{ "errmsg" : "exception: TypeError: Cannot read property 'oid' of undefined near '['$dbref'].oid, this.foo_bar )' (line 3)", "code" : 16722, "ok" : 0 } at src/mongo/shell/collection.js:970 - 有什么建议@cubitouch?
  • 我认为这里最大的问题是Java驱动程序没有标准化他们的dbrefs,我假设你从文档的其他细节中使用java
  • 我们确实使用 Java (Spring MongoDB)。我给你的输出是在 OSX 上使用 mongo cli。
  • 挂在 Ima 测试这个,没有解释为什么这不应该工作

标签: mongodb mapreduce key


【解决方案1】:

我认为真正的答案是重新审视您的架构设计。值得注意的是,Spring 数据方法更倾向于传统的关系设计,而不是 MongoDB 提供的动态文档结构。

也就是说,这里有一个link,其中包含来自 MongoDB 社区经理的更多解释和替代方案。按照该响应中包含的注释和链接进行操作。

除了重新设计之外,唯一的方法是使用输出预加入数据,这实际上只是实际进行重新设计的一种解决方法从地图减少。这是一个渐进的步骤。生成的集合将允许您查询子文档的属性,而无需通过网络将每个文档拉下来。

另外,在 MongoDB 的下一个版本中,将设置类似的输出选项添加到聚合框架管道。

【讨论】:

  • 我完全同意你的观点,模型需要尽快重新设计以更加面向文档。目前不可能这样做。您指出的link 很有趣,但无法应用给定的解决方案:我无法在 mapReduce 时间访问 DBRef 标识符!
  • 答案如何不适用?你不能做连接,你不能在不加载引用对象的情况下访问它的属性。您需要预加入另一个集合中的数据。应用编辑以澄清
  • 他不想加入,他只是想从对象中取出oid
  • @Sammaye oid 如果来自 DBRef 的 Linked 对象被称为连接。 DBRef 的目的是explained 仅作为客户端操作。如果您想从这些链接的文档中获取数据,而不是通过网络(已被声明为意图 [re: datacenter])并在客户端中处理所有内容,那么您必须将结果合并到一个集合中您可以使用的服务器。
  • 没有其他答案可以等待。 DBRef 不包含其他信息,除了哪个文档 _id 在哪个集合中,可能还有哪个数据库。获得引用文档的完整详细信息的唯一方法是从源集合中读取。因此,解决方法是不重新设计以将组合结果转储到一个可行的集合中。
猜你喜欢
  • 2012-06-16
  • 1970-01-01
  • 2012-03-09
  • 2012-08-31
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多