成功复制到CouchDB后,PouchDB删除文档

时间:2017-04-26 01:20:48

标签: javascript couchdb pouchdb nosql

我正在尝试实施如下所述的流程:

  1. 在设备中创建sale_transaction文档。
  2. sale_transaction文档放入邮袋。
  3. 由于Pouch&和Pouch之间存在实时复制。 Couch,让sale_transaction文件流向Couch。
  4. 成功将sale_transaction文档复制到Couch后,删除Pouch中的文档。
  5. 不要让Pouch中的deleted sale_transaction文件流过Couch。
  6. 目前,我已经实现了两个数据库的双向同步,我将过滤从Couch到Pouch的每个文档,反之亦然。

    对于从Couch到Pouch的复制,我不想让sale_transaction文件通过,因为我可以从Couch获取这些文件。

    PouchDb.replicate(remoteDb, localDb, {
       // Replicate from Couch to Pouch
       live: true,
       retry: true,
       filter: (doc) => {
          return doc.doc_type!=="sale_transaction";
       }
    })
    

    对于从Pouch到Couch的复制,我放入了一个过滤器,不让deleted sale_transaction文件通过。

    PouchDb.replicate(localDb, remoteDb, {
       // Replicate from Pouch to Couch
       live: true,
       retry: true,
       filter: (doc) => {
          if(doc.doc_type==="sale_transaction" && doc._deleted) {
             // These are deleted transactions which I dont want to replicate to Couch
             return false;
          }
          return true;
        }
    }).on("change", (change) => {
       // Handle change
       replicateOutChangeHandler(change)
    });
    

    在写入Couch之后,我还实现了一个更改处理程序来删除Pouch中的sale_transaction文档。

    function replicateOutChangeHandler(change) {
       for(let doc of change.docs) {
          if(doc.doc_type==="sale_transaction" && !doc._deleted) {
             localDb.upsert(doc._id, function(prevDoc) {
                if(!prevDoc._deleted) {
                   prevDoc._deleted = true;
                }
                return prevDoc;
             }).then((res)=>{
                console.log("Deleted Document After Replication",res);
             }).catch((err)=>{
                console.error("Deleted Document After Replication (ERROR): ",err);
             })
          }
       }
    }
    

    数据流似乎首先起作用,但是当我从Couch获取sale_transaction文档,然后进行一些编辑时,我将不得不重复在Pouch中编写文档的过程,然后让它流向Couch,然后在Pouch中删除它。但是,在使用相同文档进行一些编辑之后,Couch中的文档也被删除了。

    我对Pouch& amp; Couch,特别是在NoSQL中,并且想知道我是否在这个过程中做错了什么。

2 个答案:

答案 0 :(得分:1)

对于上述情况,我建议您调整方法如下:

从CouchDB创建PouchDB数据库作为复制目标,但将此数据库视为CouchDB数据库的只读镜像,应用您需要的任何转换,以便从本地存储中剥离某些文档类型。为了这个例子,让我们调用这个数据库mirrormirror数据库只能通过转换复制从规范的CouchDB数据库单向更新。

创建一个单独的 PouchDB数据库来存储所有销售交易。为了这个例子,让我们调用这个数据库user-data

当用户创建新的销售交易时,此文档将写入user-data。在user-data上监听更改,并在创建文档时,使用更改处理程序直接创建文档并将其写入CouchDB。

此时,CouchDB正在接收来自user-data的销售交易,但您的转化复制会阻止它们污染mirror。你可以保留它,在这种情况下user-data将拥有所有销售交易的本地副本。注销时,您只需删除user-data数据库即可。或者,您可以在更改处理程序中添加一些更复杂的逻辑,以便在CouchDB收到文档后删除该文档。

如果你真的想要变幻想,你可以做更精细的事情。在将销售交易写入CouchDB之后将其保留在user-data中,并在从CouchDB到mirror的转换复制中,查找这些新创建的销售交易文档。除了删除它们之外,只需删除除_id_rev字段之外的任何内容,并将其用作“收据”。当其中一个ID与user-data中的ID匹配时,可以安全删除该文档。

无论您选择哪种方法,我建议您将本地PouchDB的_changes Feed视为工作队列,而不是将所有这些精心设计的逻辑放在复制过滤器中。上述方法应该能够在不引入冲突的情况下在脱机情况下生存,并在恢复连接时恢复良好。我推荐最后一个解决方案,尽管它可能比其他解决方案多一点。希望这会有所帮助。

答案 1 :(得分:0)

也许是要删除的其他字段-因此将记录标记为要删除。 然后,在Pouch和Couch上运行的定期例程将扫描标记为删除的记录并将其删除。