Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple remote databases, single local database (fancy replication)

I have a PouchDB app that manages users.

Users have a local PouchDB instance that replicates with a single CouchDB database. Pretty simple.

This is where things get a bit complicated. I am introducing the concept of "groups" to my design. Groups will be different CouchDB databases but locally, they should be a part of the user database.

I was reading a bit about "fancy replication" in the pouchDB site and this seems to be the solution I am after.

Now, my question is, how do I do it? More specifically, How do I replicate from multiple remote databases into a single local one? Some code examples will be super.

From my diagram below, you will notice that I need to essentially add databases dynamically based on the groups the user is in. A critique of my design will also be appreciated.

enter image description here

Should the flow be something like this:

  1. Retrieve all user docs from his/her DB into localUserDB
  2. var groupDB = new PouchDB('remote-group-url'); groupDB.replicate.to(localUserDB);
    (any performance issues with multiple pouchdb instances 0_0?)
  3. Locally, when the user makes a change related to a specific group, we determine the corresponding database and replicate by doing something like:
    localUserDB.replicate.to(groupDB) (Do I need filtered replication?)
like image 977
dipole_moment Avatar asked Mar 12 '15 14:03

dipole_moment


1 Answers

Replicate from many remote databases to your local one:

remoteDB1.replicate.to(localDB);
remoteDB2.replicate.to(localDB);
remoteDB3.replicate.to(localDB);
// etc.

Then do a filtered replication from your local database to the remote database that is supposed to receive changes:

localDB.replicate.to(remoteDB1, {
  filter: function (doc) {
    return doc.shouldBeReplicated;
  }
});

Why filtered replication? Because your local database contains documents from many sources, and you don't want to replicate everything back to the one remote database.

Why a filter function? Since you are replicating from the local database, there's no performance gain from using design docs, views, etc. Just pass in a filter function; it's simpler. :)

Hope that helps!

Edit: okay, it sounds like the names of the groups that the user belongs to are actually included in the first database, which is what you mean by "iterate over." No, you probably shouldn't do this. :) You are trying to circumvent CouchDB's built-in authentication/privilege system.

Instead you should use CouchDB's built-in roles, apply those roles to the user, and then use a "database per role" scheme to ensure users only have access to their proper group DBs. Users can always query the _users API to see what roles they belong to. Simple!

For more details, read the pouchdb-authentication README.

like image 114
nlawson Avatar answered Nov 14 '22 17:11

nlawson