CouchDB视图:连接和子查询

sco*_*tes 8 couchdb

我把它发布到CouchDB-Users邮件列表中,但我想我会把网络扩大一点.

[由于stackoverflow的新用户垃圾邮件规则导致链接被破坏:-(]

希望你们中的一个聪明的人可以提供帮助(或者至少有人可以明确地告诉我我要做的事情是不可能的,而且我将不得不考虑替代方案......我听说MySQL正在接受( - :) .

背景信息:我在这里设置了一个示例数据库:scoates-test.couchone.com/_utils/database.html?follow/scoates-test.couchone.com/follow

我有两种类型的文件.type = user和type = asset.

示例用户:scoates-test.couchone.com/_utils/document.html?follow/c988a29740241c7d20fc7974be05f67d

示例资产:scoates-test.couchone.com/_utils/document.html?follow/c988a29740241c7d20fc7974be061d62

用户可以关注其他用户(type =用户文档的"关注"字段).上面的示例用户(username = bob)是"跟随"2个用户:

"following": [
   "c988a29740241c7d20fc7974be05ec54", // username=aaron
   "c988a29740241c7d20fc7974be060bb4" // username=dale
]
Run Code Online (Sandbox Code Playgroud)

资产由特定用户拥有.以上示例资产归c988a29740241c7d20fc7974be061d62所有(用户名= bob).

希望这是有道理的.

我想请求属于bob跟随的用户的资产(aaron和dale),我不能把手指放在允许这个的视图代码上.我可以轻松地发出属于c988a29740241c7d20fc7974be05f67d的所有资产.

可以在两个请求中做到这一点.首先,我向CouchDB询问c988a29740241c7d20fc7974be05f67d,然后将以下内容作为"键"发布到返回属于这些键的资产的视图,但是您会注意到我的type = assets文档也有一个"when"字段,并且我希望能够通过发出[doc.owner,doc.when]作为密钥,然后使用startKey/endKey来订购.因此,我认为密钥的POST已经出来了.

可以加入应用程序端(查询以下密钥,为每个密钥发出一个请求,然后在应用程序端排序),但这会严重破坏分页(我需要为每个密钥请求pageSize的限制)以下),并且非常快速地失控(如果用户跟踪1000个用户,那么每页有10,000个记录).

这些解决方案都不适合我.我想 CouchDB中做到这一点.

我真的很难过.请帮忙.

小号

Vic*_*let 10

CouchDB视图有一个基本规则,可以帮助您解决这类问题.

查询CouchDB视图返回零个,一个或多个键值id元组,以便从同一文档计算键,值和id.您可以选择使用提供的id(可能是也可能不是用于计算元组的文档)来请求文档.

如果你考虑它,它是相当合乎逻辑的:每个元组都是a的结果emit(),因此所有发出的数据只能来自单个文档.

在您的特定情况下,您需要使用元组键来包含:

  • 当前用户,因为您只希望该用户可以看到文档
  • 文档的"所有者",因为您需要按该值排序.
  • 文档的"when",因为您需要按该值排序.

根据基本规则,您需要一个CouchDB文档来包含所有这些.您当前的架构("用户"文档中的当前用户和文档所有者,文档所有者以及何时在"文档"文档中)未将所需数据汇集在一起​​,因此您需要对其进行更改.

我的建议是使用具有以下结构的"共享"文档:

{ 
   owner : 'id-of-aaron', 
   followers : [ 'id-of-bob', 'id-of-mike', 'id-of-melissa' ],
   docs : {
     'id-of-doc-1' : '2010-09-08',
     'id-of-doc-2' : '2010-09-07',
     'id-of-doc-3' : '2010-11-27'
   }
}
Run Code Online (Sandbox Code Playgroud)

只要用户跟随/取消关注所有者,或者所有者添加或删除文档,您就需要更新此结构.从那里,您可以简单地发出:

for (var docid in doc.docs) 
  for (var i in doc.followers) {
    emit ([doc.followers[i], doc.owner, doc.docs[docid]], { _id : docid });
  }
}
Run Code Online (Sandbox Code Playgroud)