database - 在 CouchDB 中使用 map reduce 输出更少的行

标签 database join map couchdb reduce

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

如果我对一组 10 个客户和 30 个订单执行映射函数,它将输出 40 行。有些行是客户,有些是订单。

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

基本上我不希望在输出中有单独的记录,我想将它们合并(订单到一个客户行中)并且我认为 reduce 是正确的方法?

最佳答案

这称为 View 整理,它是一种非常有用的 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 但重要的是两个文档都知道客户的身份

返回

目标是 map 查询,如果您指定 ?key="customer me@example.com" 那么您将首先返回 (1) 客户信息,然后 (2)下的所有订单。

这个 map 函数可以做到这一点:

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

附言如果您遵循所有这些:而不是 12,更好的值可能是客户的 null,然后是订单的订单时间戳。除了现在您有一个按时间顺序排列的订单列表之外,它们将与以前一样排序。

关于database - 在 CouchDB 中使用 map reduce 输出更少的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6064987/

相关文章:

c# - 在 C# 中将 Java Map 转换为 Dictionary 的最佳方法

java - 使用值中的换行符读取 java 中的 .properties 文件

map - 为什么我的unordered_map自己订购?

search - 如何在 webapp/网站上实现搜索

PHP 跳过 if block

mysql - 将图像从数据库添加到谷歌地图信息窗口

ruby-on-rails - 在rails中,如何在不删除真实记录的情况下销毁 'join table item'?

java - 我将如何着手制作高效的键值存储(例如内存缓存)/简单数据库?

mysql - LEFT JOIN 与主查询的相对值

mysql - 连接两个表以从一个表获取 COUNT,从另一个表获取 SUM