14

假设您有两种文档类型,客户订单客户文档包含姓名、地址等基本信息,订单包含客户每次订购商品时的所有订单信息。存储文件时,type = order 或 type = customer。

如果我对一组 10 个客户和 30 个订单执行地图功能,它将输出 40 行。有些行是客户,有些是订单。

问题是,我如何编写reduce,以便将订单信息“填充”在包含客户信息的行中?所以它将返回 10 行(10 个客户),但每个客户的所有相关订单。

基本上我不想在输出上单独记录,我想将它们组合起来(订单到一个客户行中),我认为减少是方法?

4

1 回答 1

30

这称为视图排序,它是一种非常有用的 CouchDB 技术。

幸运的是,你甚至不需要reduce一步。只是map用来让客户和他们的订单“聚集”在一起。

设置

关键是您需要为每个客户提供一个唯一的 ID,并且必须从客户文档和订单文档中都知道它。

示例客户:

{ "_id": "customer me@example.com"
, "type": "customer"
, "name": "Jason"
}

示例顺序:

{ "_id": "abcdef123456"
, "type": "order"
, "for_customer": "customer me@example.com"
}

我方便地使用客户 ID 作为文档_id,但重要的是两个文档都知道客户的身份

清偿

目标是地图查询,如果您指定?key="customer me@example.com",您将首先返回 (1) 客户信息,以及 (2) 任何和所有下达的订单。

这个地图功能可以做到这一点:

function(doc) {
  var CUSTOMER_VAL = 1;
  var ORDER_VAL    = 2;
  var key;

  if(doc.type === "customer") {
    key = [doc._id, CUSTOMER_VAL];
    emit(key, doc);
  }

  if(doc.type === "order") {
    key = [doc.for_customer, ORDER_VAL];
    emit(key, doc);
  }
}

所有行将主要按文档所涉及的客户进行排序,并且“决胜局”排序是整数 1 或 2。这使得客户文档总是在其相应的订单文档之上排序。

["customer me@example.com", 1], ...customer doc...
["customer me@example.com", 2], ...customer's order...
["customer me@example.com", 2], ...customer's other order.
... etc...
["customer another@customer.com", 1], ... different customer...
["customer another@customer.com", 2], ... different customer's order

PS如果您遵循所有这些:而不是1更好2的价值可能是null为客户,然后是订单的订单时间戳。除了现在您有一个按时间顺序排列的订单列表外,它们的排序方式与以前相同。

于 2011-05-20T00:55:12.203 回答