我在电子应用上使用pouchDb。在传递给pouchDb之前,数据存储在postgres数据库中。在某些情况下,要弄清楚如何以文档方式构建数据并不是很难。
我主要担心的是关系。例如:
我有数据类型项目,项目有很多事件。现在我在每个事件上都有一个名为project_id的字段。因此,当我想要获得ID为' project / 1'的项目的活动时我会做
allDocs
我已经读过include_docs: false
是效率最高的API,但是,在这种情况下,视图是否更方便?
另一方面,当我显示包含所有项目的列表时,每个项目都需要显示它拥有的事件数。在这种情况下看起来我必须再次使用{{1}}运行allDocs以计算项目所具有的事件数。
有观点可以改善这种情况吗?
另一方面,我正在考虑在Project文档中创建一个包含所有事件ID的数组,以便我可以轻松计算它有多少事件。在这种情况下,我应该使用allDocs吗?有没有办法将ID数组传递给allDocs?或者更好的是在该数组上使用循环并为每个id调用get(id)?
这种方式比第一种更有效吗?
谢谢!
答案 0 :(得分:6)
好问题!有许多方法可以处理PouchDB中的关系。和许多NoSQL数据库一样,每个数据库都会为您提供性能与便利性的权衡。
您描述的系统并不是非常高效。基本上,您正在获取数据库中的每个事件(O(n)
),然后在内存中进行过滤。如果你有很多事件,那么n
会很大,这意味着它会非常慢。
这里有几个选项。所有这些都比你现在的系统好:
map
函数中,每个事件都需要emit()
项目_id
。这将为您在key
函数中添加emit()
的内容创建二级索引。_id
并为每个allDocs()
和startkey
运行endkey
。因此,它将获取一个allDocs()
来获取项目,然后是第二个allDocs()
来获取该项目的事件。new PouchDB('projects')
和new PouchDB('events')
(粗略地说,这些是按性能最低的顺序列出的。)
#1比你描述的系统性能更高,虽然它仍然不是非常快,因为它需要创建一个二级索引,然后在二级索引数据库上基本上执行allDocs()
以及在原始数据库上(以获取链接的文档)。所以基本上你在引擎盖下运行allDocs()
三次 - 其中一个是key
发出的任何内容,它看起来你不需要,所以它只会浪费。 / p>
#2要好得多,因为它会运行两个快速allDocs()
查询 - 一个用于获取项目,另一个用于获取事件。它也不需要创建二级索引;它可以使用免费的_id
索引。
#3还需要两次allDocs()
次呼叫。那为什么它最快?好吧,有趣的是,这是因为IndexedDB如何在引擎盖下命令读/写操作。假设您正在写'projects'
和'events'
。 IndexedDB将做的是序列化这两个写入,因为它不能确定这两个写入不会修改相同的文档。 (但就读取而言,这两个查询可以在任何一种情况下同时运行 - 至少在Chrome中。我相信Firefox实际上会对读取进行序列化。)所以基本上如果你有两个完全独立的PouchDB,代表两个完全独立的IndexedDBs ,然后读取和写入都可以同时完成。
当然,在父子关系的情况下,您无法提前知道子ID,因此您无论如何都必须获取父级,然后获取子级。因此,在这种情况下,#2和#3之间没有性能差异。
在你的情况下,我会说最好的选择可能是#2。这是性能和方便之间的一个很好的折衷,特别是因为relational-pouch
插件已经为你完成了工作。