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

3
我正在尝试实现以下过程:
1. 在设备中创建一个“sale_transaction”文档。 2. 将“sale_transaction”文档放入Pouch中。 3. 由于Pouch和Couch之间存在实时复制,让“sale_transaction”文档流动到Couch。 4. 成功将“sale_transaction”文档复制到Couch后,在Pouch中删除该文档。 5. 不要让已删除的“sale_transaction”文档通过Couch流动。
目前,我已经从两个数据库实现了双向同步,其中我正在过滤从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的复制过程中,我添加了一个过滤器,以防止已删除的销售交易文档通过。

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)
});

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

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和Couch方面比较新手,尤其是在NoSQL方面,想知道我在这个过程中是否做错了什么。


为什么不直接在内存中编辑/创建文档,然后将它们直接推送到CouchDB呢? - Alexis Côté
@AlexisCôté 我在考虑设备无法访问互联网的情况。因此,如果我将文档推送到 Pouch,并且没有网络连接,我依靠 Pouch 的本地复制来将文档同步到 Couch。 - aamiel16
2个回答

2
针对您描述的情况,我建议您采取以下方法:
从CouchDB创建一个PouchDB数据库作为复制目标,但将此数据库视为CouchDB数据库的只读镜像,在本地存储中应用所需的任何转换以剥离某些文档类型。在本示例中,我们将此数据库称为“mirror”。 “mirror”数据库仅单向更新,通过转换复制从规范的CouchDB数据库更新。
创建一个单独的PouchDB数据库来存储所有销售交易。在本例中,我们将此数据库称为“user-data”。
当用户创建新的销售交易时,该文档将写入“user-data”。监听“user-data”的更改,当创建文档时,使用更改处理程序直接创建并写入文档到CouchDB。
此时,CouchDB正在从“user-data”接收销售交易,但是您的转换复制正在防止它们污染“mirror”。您可以将其保留在那里,这样“user-data”将具有所有销售交易的本地副本。在注销时,您只需删除“user-data”数据库。或者,您可以在更改处理程序中添加一些更复杂的逻辑,以在CouchDB接收到文档后删除文档。
如果您真的想要变得更加复杂,您可以做更多的事情。在将销售交易从CouchDB复制到“mirror”的转换复制中,留下销售交易在“user-data”中,查找这些新创建的销售交易文档。而不是删除它们,只剥离其除“_id”和“_rev”字段之外的所有内容,并将其用作“收据”。当其中一个ID与“user-data”中的ID匹配时,可以安全地删除该文档。
无论您选择哪种方法,我建议您将本地PouchDB的“_changes”提要视为工作队列,而不是将所有这些复杂逻辑放入复制过滤器中。上述方法都应该能够在离线情况下生存而不会引入冲突,并在恢复连接时恢复良好。我建议您选择最后一种解决方案,尽管可能需要比其他解决方案更多的工作。希望这有所帮助。

0

或许需要一个额外的字段来进行删除操作 - 标记待删除记录。 然后,定期运行在 Pouch 和 Couch 上的例行程序会扫描标记为待删除的记录并将其删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接