如何使用 2 个或更多 SQL 连接进行查询

How to query with 2 or more SQL joins

我的 CouchDB 数据库有 3 种类型的数据:A、B、C。

例如:

{ _id:"a1", type:"A", name:"aaaaa", b:"b1" }
{ _id:"b1", type:"B", name:"bbbbb", c:"c1" }
{ _id:"c1", type:"C", name:"ccccc" }

我想在一个视图中查询所有 As,并检索其 B 的名称及其 B 的 C(例如,我想将结果限制为仅获取 As of which C的名字是"cc").

我怎样才能做到这一点?

(只得到A和B,答案是:

map: function (doc) {
  if (doc.type == "A") {
    emit([doc._id,0])
    emit([doc._id,1], { _id: A.b })
  }
}

但我不知道可以扩展到第二段关系)

如果我们有 'D' class 和 'E' class 等具有更多嵌套关系的情况,我也对答案感兴趣。

非常感谢!

一般而言,在 CouchDB 中,只能遍历一个图的一层深度。如果您需要更多级别,使用专门的图形数据库可能是更好的方法。

有多种方法可以在 CouchDB 中实现您想要的功能,但您必须根据用例对文档进行建模。

  • 如果您的 "C" 类型大部分是静态的,您可以将名称嵌入文档本身。每当您修改一个 C 文档时,只需批量更新所有引用该 C 的文档。
  • 在许多情况下,甚至不需要 C 类型文档或从 ​​B 到 C 的引用。例如,如果 C 是标签文档,您可以只在 B 文档中存储一个字符串数组。
  • 如果需要A中的C,也可以在A中存入C的引用,最好附上A中缓存的C的名字,这样如果C已经被删除了,还可以使用缓存的值。
  • 如果其中一种文档类型的实例很少,您也可以直接嵌入它们。根据用例,您可以将 B 嵌入到 A 中,您可以将所有 A 嵌入到 B 中的一个数组中,或者您甚至可以将所有内容都放入一个文档中。

对于 CouchDB,考虑文档更新的频率和分布比规范化数据更有意义。

这种思维方式与您对 SQL 数据库的思维方式截然不同,但在我们在网络上拥有的典型的以读取为主的场景中,与建模昂贵的读取查询相比,这是一个更好的权衡像独立实体这样的文档。

当我为 CouchDB 文档建模时,我总是将其视为护照或商业信函。这是一个拥有有效、正确和完整信息的单一实体,但不能严格保证我仍然和护照上的一样高,我看起来和照片上的一模一样,我没有改变我的名字,或者我地址与商业信函上的地址不同。

如果您提供更多关于您实际想用一些示例做什么的信息,我将很乐意进一步详细说明!