6

我正在使用似乎是创建连接视图的常用技巧:

// a Customer has many Orders; show them together in one view:
function(doc) {
  if (doc.Type == "customer") {
    emit([doc._id, 0], doc);
  } else if (doc.Type == "order") {
    emit([doc.customer_id, 1], doc);
  }
}

我知道我可以使用以下查询来获取单个customer和所有相关Order的 s:

?startkey=["some_customer_id"]&endkey=["some_customer_id", 2]

但是现在我已经将我的查询与我的视图代码非常紧密地联系在一起。是否有一个值可以放在我的“ 2”处,以便更清楚地说,“我希望一切都与这个客户相关联”?我想我见过

?startkey=["some_customer_id"]&endkey=["some_customer_id", {}]

但我不确定那{}肯定排在其他所有事情之后。

归功于 cmlenz的join 方法。

CouchDB wiki page on collat​​ion的进一步说明:

该查询startkey=["foo"]&endkey=["foo",{}]将匹配第一个元素中带有“foo”的大多数数组键,例如["foo","bar"]and ["foo",["bar","baz"]]。但是它不会匹配["foo",{"an":"object"}]

所以在排序顺序{}很晚,但绝对不是最后一个

4

5 回答 5

2

我有两个想法。

使用时间戳

与其使用简单的 0 和 1 作为其整理行为,不如使用创建记录的时间戳(假设它们是记录的一部分) a la [doc._id, doc.created_at]。然后,您可以使用某个足够早的日期的开始键(纪元可能会起作用)和“现在”的结束键来查询您的视图,例如date +%s. 该关键范围应始终包括所有内容,并且它具有按日期整理的额外好处,这可能是您想要的。

或者,别担心

您可以只按 customer_id 进行索引,仅此而已。这将具有能够使用 just 进行查询的好处key=<customer_id>。当然,记录回来时不会被整理,但这对您的应用程序来说是个问题吗?除非您期望返回大量记录,否则一旦您的应用程序检索到数据,简单地将客户记录从列表中取出可能是微不足道的。

例如在红宝石中:

customer_records = records.delete_if { |record| record.type == "customer" }

无论如何,时间戳可能是您的案例更具吸引力的答案。

于 2009-11-10T18:45:24.903 回答
1

我建议不要尝试为数组键中的第二个元素找到最大可能值,而是尝试找到大于第一个:的最小可能值。?startkey=["some_customer_id"]&endkey=["some_customer_id\u0000"]&inclusive_end=false

于 2010-10-05T03:31:29.067 回答
0

CouchDB 主要是用 Erlang 编写的。我不认为除了系统资源之外的字符串复合/复合键元组大小没有上限(例如,只要它使用所有可用内存的键)。根据 CouchDB 站点,CouchDB 可扩展性的限制是未知的。我猜你可以继续将字段添加到一个巨大的复合主键中,唯一会阻止你的是系统资源或硬限制,例如目标架构上的最大整数大小。

由于 CouchDB 使用 JSON 存储所有内容,因此它可能仅限于 ECMAScript 标准的最大数值。JavaScript 中的所有数字都存储为浮点 IEEE 754 双精度数。我相信 64 位双精度可以表示从 - 5e-324 到 +1.7976931348623157e+308 的值。

于 2009-07-25T03:54:30.670 回答
0

拥有一个 endKey 可以是包容性而不是独占性的功能似乎会很好。

于 2009-10-30T09:30:01.180 回答
0

这应该可以解决问题:

?startkey=["some_customer_id"]&endkey=["some_customer_id", "\uFFFF"]

这应该包括以小于 \uFFFF 的字符开头的任何内容(所有 unicode 字符)

于 2009-11-10T10:41:19.467 回答