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



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

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

我的数据类型是Projects,Projects有很多事件。现在,我在每个事件上都有一个名为project_id的字段。因此,当我想获得ID为"project/1"的项目的事件时,我会进行

_db.allDocs({
   include_docs: true,
   startkey: 'event',
   endkey: 'eventuffff'
}).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,但是,在这种情况下查看视图是否更方便?

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

有观点能改善这种情况吗?

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

这另一种方式比第一种方式更具表演性吗?

谢谢!

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

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

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

  1. map/reduce中的链接(又称连接)文档。也就是说,在map函数中,您将为每个事件emit()项目_id。这将在emit()函数中作为key放置的内容上创建一个辅助索引
  2. relational pocket,这是一个插件,它使用前缀_ids并运行allDocs(),每个插件使用startkeyendkey。因此,它将执行一个allDocs()来获取项目,然后执行第二个allDocs()来获取该项目的事件
  3. 完全独立的数据库,例如new PouchDB('projects')new PouchDB('events')

(大致按性能最低到性能最高的顺序列出。)

#1比您描述的系统性能更高,尽管它仍然不是很快,因为它需要创建一个辅助索引,然后在辅助索引数据库和原始数据库上执行allDocs()(以获取链接的文档)。所以基本上你在引擎盖下运行allDocs()三次–其中一个是你发射的key,看起来你不需要它,所以它会被浪费掉。

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

#3还需要两个CCD_ 23调用。为什么它是最快的?有趣的是,这是因为IndexedDB是如何在后台对读/写操作进行排序的。假设您同时写信给'projects''events'。IndexedDB将要做的是序列化这两个写入,因为它不能确定这两个不会修改相同的文档。(不过,当涉及到读取时,至少在Chrome中,这两个查询在任何一种情况下都可以同时运行。我相信Firefox实际上会序列化读取。)因此,基本上,如果您有两个完全独立的PouchDB,代表两个完全分离的IndexedDB,那么读取和写入都可以同时进行。

当然,在父子关系的情况下,你不能提前知道孩子的ID,所以你无论如何都必须先取父母,然后再取孩子。因此,在这种情况下,#2和#3之间没有性能差异。

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

最新更新