CouchDB查看索引性能

时间:2014-07-22 07:48:32

标签: couchdb

我对我的观点编制索引的最佳方法有些怀疑。

假设我存储了将“用户”链接到“群组”的文档:

{
  "groupId": "<group_id>",
  "userId": "<user_id>"
}

我想检索链接到用户的所有组,因此显然最好的映射方式是:

emit(doc.userId, doc.groupId);

我可以通过key=<user_id>查询视图来检索群组。

但是现在如果我想删除与特定用户/组对应的文档,我需要查看视图查询的所有结果,直到我找到正确的值并获得文档的ID。

所以我认为索引视图的更好方法就是:

emit([doc.userId, doc.groupId], null);

现在,我可以通过发出范围查询并解析返回行的键来获取链接到用户的所有组,并使用“完整”键直接命中特定文档(如果存在)。但是我担心范围查询(将比“完整”方式更频繁地称为方式)将比最初的方法具有更差的性能。

在此感谢任何见解,谢谢!

2 个答案:

答案 0 :(得分:2)

我相信你应该抵制创造太多小文件的冲动(我们从SQL数据库经验中带来了这些文件)。在这个(公认的例子)用例中,单个组的用户列表或单个用户的组列表可以是单个文档。

显然,单个组的用户很可能会有多个并发编辑导致冲突 - 但对单个用户的组列表进行多次并发编辑的可能性较小。

因此,我主张您为每个用户创建一个列出其组的单个文档(或者只是将其作为数组添加到其他一些用户关注的文档中)。使用基于用户ID的固定文档ID方案,以便您可以直接通过ID访问文档,而无需在视图中查找。现在,您只需要为特定组发出用户视图。

如果用户离开群组,您只需更新群组偏好设置即可。如果一个组被删除,那么您就可以从每个组成员的首选项中找到并删除组ID,但这将是一个不太频繁的任务,通常只能由更长时间容忍的管理员执行。运行过程。

答案 1 :(得分:1)

当然,最终的答案是衡量对您来说重要的指标。

但是,我认为性能大致相同。在每种情况下,您将为每个{user,group}对发出一个视图行。

视图可以包含多个具有相同&#34;键的行。&#34;因此,当您查询key=<user_id>时,您仍在进行范围查询(&#34; CouchDB,请显示所有以user_id开头且以user_id结尾的视图行。&#34;)所以我认为您会看到类似的在那里表现。

对我而言,您最大的性能问题看起来像延迟:多次往返查询此视图,然后跟进文档。您当然可以添加?include_docs=true,但仍会增加额外的i / o负载。 (在我看来,额外的成本主要是理论上的,在实际应用中并没有那么糟糕。)

要删除文档,您需要的不仅仅是ID。你也需要修改。因此,为了略微提高性能并减少往返和延迟,您可以发出更有用的值而不是null。例如,发出整个文档!或者发出{"_id":doc._id, "_rev":doc._rev}。这样,你可以删除文件&#34;看不见的&#34;通过向/db/<id>?rev=<rev>发出删除。