javascriptcouchdbpouchdb

PouchDB delete data on device without affecting remote sync


Right now I am replicating my entire device database over to my remote database.

Once that is complete, I grab all my data that is not older than 1 month from my remote database, using a filter, and bring it to my device.

FILTER

{
  _id: '_design/filters',
  "filters": {
    "device": function(doc, req) { 
      if(doc.type == "document" || doc.type == "signature") { 
        if(doc.created >= req.query.date) return true;
        else return false;
      } 
      else return true;
    }
  }
}

REPLICATION

device_db.replicate.to(remote_db)
.on('complete', function () {

  device_db.replicate.from(remote_db, {

    filter: "filters/device", 
    query_params: { "date": (Math.floor(Date.now() / 1000)-2419200) }

  })
  .on('complete', function () {

    console.log("localtoRemoteSync replicate.to success");
    callback(true);

  });

});

My question:

I want to be able to periodically delete data from my device that is older than 3 months (old enough data where I already know it's been sync'd)

But just because I delete it from my device, when I replicate the data back to my remote_db, I don't want it to be deleted on there too.

How can I delete specific data on my device but not have that deletion translated when I replicate?


Solution

  • FILTERS

    Here, we have 2 filters:

    noDeleted : This filter doesn't push _deleted documents.

    device : Filter to get the latest data only.

    {
      _id: '_design/filters',
      "filters": {
          "device": function(doc, req) {
              if (doc.type == "document" || doc.type == "signature") {
                  if (doc.created >= req.query.date) return true;
                  else return false;
              }
              return true;
          },
           "noDeleted": function(doc, req) {
              //Document _deleted won't pass through this filter.
              //If we delete the document locally, the delete won't be replicated to the remote DB 
              return !doc._deleted;
          }
      }
    }
    

    REPLICATION

    device_db.replicate.to(remote_db, {
          filter: "filters/noDeleted"
      })
      .on('complete', function() {
          device_db.replicate.from(remote_db, {
                  filter: "filters/device",
                  query_params: { "date": (Math.floor(Date.now() / 1000) - 2419200) }
              })
              .on('complete', function() {
                  console.log("localtoRemoteSync replicate.to success");
                  callback(true);
              });
      });
    

    Workflow

    1. You push all your documents without pushing the deleted document.
    2. You get all the updates for the latest data
    3. You delete your old documents
      • You could either query the remote DB to get the ids of the documents that are too old and delete them locally. Note that the documents will still be there as _deleted. To completely remove them, a compaction will be required.
      • You could also totally destroy your local database after step1 and start from scratch.
    4. callback(true);