CouchDB:在Reduce函数中合并对象

时间:2015-06-18 16:07:33

标签: dictionary mapreduce views couchdb reduce

我是CouchDB的新手,所以请耐心等待。我在搜索SO以寻找答案,但无法将其缩小到具体的范围。

我有一个mapper函数,可以为用户创建值。用户看到了不同的产品页面,我们想要统计他们所见过的类型和产品。

var emit_values = {};
emit_values.name = doc.name;
...
emit_values.productsViewed = {};
emit_values.productsViewed[doc.product] = 1

emit([doc.id, doc.customer], emit_values);

在reduce函数中,我想为该给定用户的productsViewed对象收集不同的值。所以在减少之后,我有了这个:

productsViewed: {
   book1: 1,
   book3: 2, 
   book8: 1
}

不幸的是,这样做会产生减少溢出错误。根据其他帖子,这是因为productsViewed对象在reduce函数中的大小正在增长,而Couch并不喜欢这样。 here

  

新CouchDB用户犯的一个常见错误是尝试使用reduce函数构造复杂的聚合值。完全减少应该产生标量值,例如5,而不是例如带有一组唯一键和每个键的计数的JSON哈希值。

所以,我知道这不是在Couch中做到这一点的正确方法。有没有人了解如何在reduce之后将值正确地收集到文档中?

1 个答案:

答案 0 :(得分:0)

您可以简单地构建一个以客户为关键字的视图

emit(doc.customer, doc.product);

然后你可以打电话

/:db/_design/:name/_view/:name?key=":customer"

获取用户查看过的所有产品。

如果客户可以多次查看产品,则可以构建多键视图

emit([doc.customer, doc.product], null);

并使用内置函数_count

减少它
 /:db/_design/:name/_view/:name?startkey=[":customer","\u0000"]&endkey=[":customer","\u9999"]&reduce=true&group_level=2

你必须接受你不能

  

构建复杂的聚合值

通过请求视图,使用CouchDB

。如果你想拥有一个像你希望的有效载荷那样的数据结构

productsViewed: {
  book1: 1,
  book3: 2, 
  book8: 1
}

我建议在客户文档上使用_update处理程序。记录产品访问的每个请求都会为customer.productsViewed属性添加值,而不是创建新文档。