How delete a document on *all* mobiles but not on server


#1

I want to archive documents on a device that will be archived on every other devices, and not synced anymore. New users should not see them ever. Server keeps all.

I din’t find my answer on this forum. My question is related to that post : Deleting documents locally while keeping them in server, but is a little bit different.

What I have :

  • Mobile users with couchbase-lite-ios
  • Web users
  • Mobile users create documents, maybe 1000 per day, that are synced. with other devices.
  • A single user can archive a set of documents. I have a property ‘archived’ on each document.

What I want :

  • I want to sync every documents on each device that are not archived.
  • I want to keep on the server every documents, including archived, for web users.
  • I want to “delete” or “hide” archived documents on every devices.
  • When a new user logs in, I don’t want him to fetch the whole history of documents, I just want him to get “live” documents.

What I did :

I created two channels : “live” and “archived”. When a user archive a document on a device, he sets the property “archived” to 1 and the sync function handles that change by changing the channel of the document.

  • In the sync_gateway fonction :
    if (doc.archived === 1) { channel('archived'); } else { channel('live'); }

  • In couchbase-lite-ios :
    CBLReplication *pullReplication = [database createPullReplication:remoteDbURL]; pullReplication.continuous = YES; pullReplication.channels = @[@"live"]; [pullReplication start];

What didn’t work :

The problem is : devices are syncing every revisions that was in “live” channel, and stops when channel changes.

That means for example, when a user archive a document, and at the same time changes the “name” property from “foo” to “bar”, every other devices will keep the old version “foo”. I think I shouldn’t see documents that are not in channels I track. Why the pull replication doesn’t ‘purge’ or ‘delete’ documents that are no longer in the channels it subscribe to ?

And the worst : when a new user logs in, he fetches the whole data revisions until they were archived, that could be a lot of documents.

I maybe misunderstand what channels do.

Is it the good approach and I just missed something ? Or am I on the wrong way ?


#2

Hi @mastohhh,
I think the purge method can get you some of the way, please read more about it here:
http://developer.couchbase.com/mobile/develop/guides/couchbase-lite/native-api/document/index.html

Purging a document is different from deleting it; it’s more like forgetting it. The purge method removes all trace of a document (and all its revisions and their attachments) from the local database. It has no effect on replication or on remote databases, though.

Purging is mostly a way to save disk space by forgetting about replicated documents that you don’t need anymore. It has some slightly weird interactions with replication, though. For example, if you purge a document, and then later the document is updated on the remote server, the next replication will pull the document into your database again.

I hope this helps


#3

Hi @martinesmann,

Thank you for your answer.

I tried this purge method. Unfortunately it does half of the work.

I want my archived documents to be :

  • Purged on my device : OK
  • Purged on every other devices.
  • Not downloaded by new users.

That’s what I tried with channels, but I saw that everything was done on a document before archiving it (ie. before changing his channel) is still synced between devices.

I want my “archived” document to act like it had never exist in “live” channel.


#4

It sounds like you want docs with the archived flag to be pulled by users who already have the document (so they get the latest revision with any property changes in addition to the archived flag), but not by users who don’t already have the document.

I think you can do that using a validation function in the device’s local database. This function would reject a doc with an archived flag, if there isn’t already an existing revision of that document in the database.


#5

Hi @jens,

Thank you. This could resolve my problem, but that means the server will send anyway all documents (all revisions that were in the live channel).

Is it possible to do the exact same thing, but on the server side ? I mean : before the document comes entirely on the mobile ?


#6

Well our system doesn’t directly support sending a revision to clients that already have that document but not to clients that don’t already have it. I can’t think of any perfect way to do what you need; the validation function is the best that comes to mind right now.


#7

Jens,

What if somebody wants the reverse: be able to archive and delete documents on the server side but not touch the document on the mobile client(data delivered is user owned) because of legal requirements? Whats the typical approach for this? Assume that the channels are still assigned and access is still intact.


#8

If you purge the document in SG, it will leave it behind on any client that already has it, but it won’t exist on the server any more and it won’t get pushed to any other clients.


#9

Ok thank you.

The original problem is : our users create thousands of documents per day, and a replication of 50000 documents can take several minutes. This is a huge problem for us. A user just wants to have “lasts” or “live” documents to work with when he launches his app. He can’t wait 10 minutes before using app with good data.

Are you working on a feature that allows to be “in sync” much faster ? Something that doesn’t send and run the whole history of revisions on devices ?

These questions should be in an other topic ?


#10

Sorry if this is a little off topic.
@Jens I could not find a purge api for the server side(sync gw). Can you please post a link here.

Also, will the document still remain in deleted state when the client updates it or will it sync back to the server?

Thx.


#11

Maybe something like replicate only last 5 days worth of data at the start of the app will help. Can we achieve this with the available api? I see only filtered based on channel but can that be tuned for such a case? What would be the overhead for such a datetime compare per channel?


#12

It’s sounds good.

Maybe I can create channels with date in its name. Example live_20150819, and the replication object only subscribe to the last week channels ?

I’ll just have to play with access() function in sync gateway …


#13

Yes, that’s the way we recommend solving the “only pull the recent changes” problem.


#14

Ok thank you. I’ll try this.

But last question, is there a maximum number of channels ? Have you performance issues with large number of channels (in my example 1 per user per day, a thousand of users) ?


#15

No, there’s no maximum number. Channels are pretty lightweight, they’re not explicitly created or destroyed.

I haven’t worked on that area of SG in a while, so my knowledge of channel handling is probably out of date, but from what I remember the overhead is more about the total number of doc-to-channel assignments (i.e. assigning every doc to hundreds of channels would get expensive), and about the number of channels that a user has access to and pulls from.