我在电子应用程序上使用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
将很大,这意味着它将非常非常慢。
这里有几个选项。所有这些都比您当前的系统更好:
- map/reduce中的链接(又称连接)文档。也就是说,在
map
函数中,您将为每个事件emit()
项目_id
。这将在emit()
函数中作为key
放置的内容上创建一个辅助索引 - relational pocket,这是一个插件,它使用前缀
_id
s并运行allDocs()
,每个插件使用startkey
和endkey
。因此,它将执行一个allDocs()
来获取项目,然后执行第二个allDocs()
来获取该项目的事件 - 完全独立的数据库,例如
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
插件已经为您完成了这项工作。