CouchDB过滤复制 - 删除文档

Der*_*ins 6 replication couchdb

我正在尝试在主数据库和用户数据库之间设置过滤复制.主服务器中的文档包含具有该文档权限的用户组列表.

{
  _id: 'one',
  groups: ['a', 'b']
}

{
  _id: 'two',
  groups: ['c', 'd']
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个数据库的过滤视图,该视图仅允许具有该组的用户获取复制文档的副本(在此示例中硬编码"a"组)

{
  filters = {
    users = function(doc, req){
      return doc.groups.indexOf(req.query.group) != -1;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,我在_replicator数据库中创建一个复制文档

{
  source: "master",
  target: "user1",
  filter: "replication/user",
  query_params: {group: "a"},
  create_target: true
}
Run Code Online (Sandbox Code Playgroud)

创建此文档后,复制开始,文档"one"从master复制到user1.文件"两个"没有被复制 - 正是我想要的.

随后,用户从组'a'移动到组'c',因此我创建了一个新的复制文档:

{
  source: "master",
  target: "user1",
  filter: "replication/user",
  query_params: {group: "c"},
  create_target: true
}
Run Code Online (Sandbox Code Playgroud)

我想要的行为是从用户数据库中删除文档"one",并复制文档"two".当它发生时,文件'one'仍然存在,文件'two'被复制.显然,除非在源数据库中删除文档,否则复制筛选器不允许删除目标数据库.

那么如何处理这种情况呢?或者我应该考虑另一种结构吗?

Aks*_*rma 2

据我所知,没有办法使用复制来修改文​​档。但您可以采取两种方法。

首先,您可以创建一个新数据库并复制到其中。例如,如果您的查询参数更改为user c而不是复制它以user1创建另一个数据库some name并复制到它,然后删除原始数据库(或保留它以防您再次查询参数更改)。您甚至可以为源数据库使用描述性名称,例如“user1_filter_a”。这是最省事的方法,但如果文档数量很大且重叠(例如属于 a 组和 c 组的大量用户 b),并且您的复制器过滤器快速更改,则效率可能会很低。

另一种方法是使用viewBulk document api。首先创建一个emits基于组字段的文档视图,如下所示

function map(doc){

     emit(doc.groups,doc._id);

  } 
Run Code Online (Sandbox Code Playgroud)

然后查询

startkey=["a"]&endKey=["a",{}]&include_docs=true

获取您要删除的所有文档。然后迭代结果集并附加到 doc._deleted=true每个文档并向数据库发出批量请求。所有文档都将被删除(更多解释请参见此处)。这种方法的优点是您可以保留单个数据库。

简而言之,如果您想保留单个数据库,则必须手动删除文档。但是,如果您基于复制器功能开放多个数据库,则每次过滤器更改时都可以创建一个新数据库。