CouchDB:在 Reduce 函数中合并对象

CouchDB: Merging Objects in Reduce Function

我是 CouchDB 的新手,请多多包涵。我在 SO 中搜索了答案,但无法具体缩小范围。

我有一个为用户创建值的映射函数。用户看到了不同的产品页面,我们想统计他们看到的类型和产品。

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 不喜欢这样。 Specifically:

A common mistake new CouchDB users make is attempting to construct complex aggregate values with a reduce function. Full reductions should result in a scalar value, like 5, and not, for instance, a JSON hash with a set of unique keys and the count of each.

所以,我知道这不是在 Couch 中执行此操作的正确方法。有没有人知道如何在 reduce 后正确地将值收集到文档中?

您只需构建一个以客户为键的视图

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

你必须接受你不能

construct complex aggregate values

通过请求视图使用 CouchDB。如果你想要一个像你想要的有效载荷那样的数据结构

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

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