CouchDB 和 PouchDB 之间的过滤同步

Filtered Sync between CouchDB and PouchDB

我目前正在考虑在我要编写的下一个应用程序中使用 CouchDB 2 和 PouchDB 7。基本上我会在中央存储中有一个 CouchDB,Web 客户端和移动应用程序将启动一个会思考的 PouchDB。基本上这就像一个魅力。

但是...如果过滤器应该基于文档所有权完成,我该如何在 CouchDB 和 PouchDB 之间进行过滤同步?

我知道每个用户数据库的解决方案。但是我的文档将由文档的创建者和 he/she 添加为 reader 或作者的人共享访问权限。

2018年有解决这个问题的方法吗?早在 2016 年,我就无法解决这个问题并放弃了应用程序的想法。

您应该在文档中包含限制文档访问、所有权、授权用户所需的信息。

根据此信息,CouchDB 和 PouchDB 之间的过滤复制定义有两个选项(检查过滤选项)。

  1. 基于 CouchDB 设计文档中定义的 JavaScript 过滤器函数。 Filter functions 允许您实现过滤逻辑,接受请求期间提供的参数作为 URL 参数或通过 req 参数在 CouchDB 中进行身份验证的用户。

    这种方法的主要问题是,只要数据库增长,您就会注意到性能下降。过滤器应用于数据库中的每个文档,甚至是已删除的文档,以产生结果。因此,如果您预见到数据库中会有大量文档,我不建议使用这种过滤机制。这里有这种 problems.

    的示例

    对这个性能问题的一个小改进是用 Erlang 编写你的过滤逻辑,这比 JS 选项复杂一点,在我的测试中,我没有设法从中获得很大的收获。

  2. 在 CouchDB 2.x 中,有使用 selectors 执行过滤复制的选项。选择器 可以被索引,据报道 比 JS 过滤器快 10 倍。选择器完全由客户端定义,不基于数据库中的身份验证上下文。此选项的扩展性比前一个好得多。

无论如何,过滤允许您在复制过程中进行一些数据库分段,但它不是文档级读取权限的安全机制。

文档写入权限可以使用validate document update functions实现。


更新 我重新审视了这个答案,试图提供有关数据库过滤机制的更准确信息。我测试了不同过滤方法的性能,试图确认答案陈述。

我加载了一个包含 9000 个文档的数据库,并使用四种技术对 _changes 提要过滤进行了时间测量:JS 过滤、Erlang 过滤、Mango 选择器过滤和 Doc id 过滤,结果如下:

  • JS 过滤 9000 个文档 - 4.3 秒
  • Erlang 过滤 9000 个文档 - 2.3 秒
  • Mango 选择器过滤 9000 个文档 - 0.48 秒
  • 过滤 9000 个文档的文档 ID - 0.01 秒

测试确认 JS 过滤是最糟糕的选择,因为它需要在外部进程中评估过滤条件,这会引入额外的开销。 Erlang 和 Mango 表达式在过滤过程中进行评估,这代表了真正的性能提升。

为了验证文档数量对过滤的影响,我创建了一个包含 20.000 个文档的数据库,并执行了相同的测试,结果如下:

  • JS 过滤 20.000 个文档 - 10 秒
  • Erlang 过滤 20.000 个文档 - 5.45 秒
  • Mango 选择器过滤 20.000 个文档 - 1.07 秒
  • 过滤 20.000 个文档的文档 ID - 0.01 秒

JS、Erlang 和 Mango 过滤时间增量与文档的数量成线性关系。这些过滤机制不使用索引。 Doc ids 过滤是恒定的,因为它基于 _id 索引。