database - 从 pouchdb 数据库中读取关系的最有效方法是什么

标签 database couchdb pouchdb document-oriented-db

我在电子应用程序上使用 pouchDb。在传递给 pouchDb 之前,数据存储在 postgres 数据库中。在某些情况下,不难弄清楚如何以文档方式构建数据。

我主要关心的是关系。例如:

我有数据类型项目,项目有很多事件。现在我在每个事件上都有一个名为 project_id 的字段。因此,当我想获取 ID 为“project/1”的项目的事件时,我会这样做

_db.allDocs({
   include_docs: true,
   startkey: 'event',
   endkey: 'event\uffff'
}).then(function(response){
   filtered = _.filter(response['rows'], function(row){
      return row['doc']['project_id'] == 'project/1'
   });
   result = filtered.map(function(row){
      return row['doc']
   })
});

我读到过 allDocs 是性能最高的 API,但是,在这种情况下使用 View 是否更方便?

另一方面,当我显示包含所有项目的列表时,每个项目都需要显示它拥有的事件数。在这种情况下,我似乎必须再次运行 allDocs,使用 include_docs: false 来计算项目的事件数。

拥有 View 是否可以改善这种情况?

另一方面,我正在考虑在项目文档中创建一个包含所有事件 ID 的数组,这样我就可以轻松计算它有多少事件。在这种情况下,我应该使用 allDocs 吗?有没有办法将一组 ID 传递给 allDocs?或者在该数组上使用循环并为每个 id 调用 get(id) 会更好吗?

这种其他方式是否比第一种方式更高效?

谢谢!

最佳答案

好问题!在 PouchDB 中有很多处理关系的方法。与许多 NoSQL 数据库一样,每个数据库都会让您在性能与便利性之间进行权衡。

您描述的系统性能不是很好。基本上,您要获取数据库中的每个事件 (O(n)),然后在内存中进行过滤。如果您有很多事件,那么 n 会很大,这意味着它会非常非常慢。

这里有几个选项。所有这些都比您当前的系统更好:

  1. Linked (aka joined) documents in map/reduce . IE。在您的 map 函数中,您将为每个事件 emit() 项目 _id。这会为您在 emit() 函数中作为 key 放置的任何内容创建二级索引。
  2. relational-pouch ,这是一个插件,它通过使用带前缀的 _id 和运行 allDocs() 以及 startkeyendkey 来工作每一个。因此它会执行一个 allDocs() 来获取项目,然后执行第二个 allDocs() 来获取该项目的事件。
  3. 完全独立的数据库,例如new PouchDB('projects')new PouchDB('events')

(大致上,这些是按性能从最低到最高的顺序列出的。)

#1 比您描述的系统性能更高,尽管它仍然不是非常快,因为它需要创建一个二级索引,然后基本上会在二级索引上执行 allDocs()索引数据库以及原始数据库(以获取链接的文档)。所以基本上你在引擎盖下运行了三次 allDocs() —— 其中一次是在你作为 key 发出的任何东西上,看起来你不需要,所以它只会被浪费。

#2 要好得多,因为它在后台运行两个快速 allDocs() 查询 - 一个用于获取项目,另一个用于获取事件。它也不需要创建二级索引;它可以使用免费的 _id 索引。

#3 还需要两次 allDocs() 调用。那么为什么它是最快的呢?好吧,有趣的是,这是因为 IndexedDB 如何在底层命令读/写操作。假设您正在写信给 'projects''events'。 IndexedDB 将做的是序列化这两个写入,因为它不能确定这两个不会修改相同的文档。 (不过,当涉及到读取时,这两个查询可以在任何一种情况下同时运行——至少在 Chrome 中是这样。我相信 Firefox 实际上会序列化读取。)所以基本上如果你有两个完全独立的 PouchDB,代表两个完全独立的 IndexedDB , 那么读写就可以同时进行了。

当然,在父子关系的情况下,你不可能事先知道 child 的ID,所以无论如何你都要先取父再取 child 。所以在那种情况下,#2 和#3 之间没有性能差异。

在你的情况下,我会说最好的选择可能是#2。这是性能和便利性之间的一个很好的折衷,特别是因为 relational-pouch 插件已经为您完成了这项工作。

关于database - 从 pouchdb 数据库中读取关系的最有效方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34346012/

相关文章:

database - Cassandra 数据库行大小是否受可用内存限制?

database - CakePHP:使用 save() 添加/减去?

reactjs - 与过滤复制同步 pouchdb

couchdb - 如何让 Couchdb/Cloudant 设计文档准备好搜索所有字段?

database - 数据库记录如何存储在磁盘上?

c# - 使用 ID 将表中的值解析为另一个表

Heroku 上的 Django

javascript - CouchDB _changes 通知 - jquery.couch.js couch.app.db.changes() 用法

javascript - 将本地存储重构为 PouchDB

javascript - Redux 存储和 PouchDB 未与 redux-pouchdb 同步