Best approach to store multiple user data is per user per database. I am using this same approach.
I have couchdb on server and pouchdb for mobile application. I am maintaining each user data by creating separate database for the user in pouchdb and couchdb. That.That means i have multiple database in couchdb and one database in pouchdb.
usually in sqlbase database user data is store in different different table.
so in nosql pouchdb i am creating document for each table.
Actual problem i am facing is:
I have one document in each database that stores the transactions of user.
Client transaction is stored in pouchdb when he/she is offline and when application get on-line transaction sync to couchdb user database in to transaction document.
data is stored in transaction document is as follows
{
"_id":"transaction ",
"_rev":"1-3e5e140d50bf6a4d873f0c0f3e3deb8c",
"data":[
{
"transaction_id":"tran_1",
"transaction_name":"approve item",
"status":"Pending",
"ResultMsg":""
},
{
"transaction_id":"tran_2",
"transaction_name":"approve item",
"status":"Pending",
"ResultMsg":""
}]
}
All these transaction is performed on server side and result is updated in these document.when ever any new transaction performed i store it in transaction document in data attribute.
Now i have 1 transaction in pouch and couchdb both means both are in sync.
Now when mobile application is offline it perform offline transaction that is stored in pouchdb transaction doc.
and on server side that 1 transaction is updated to success.
Now when application goes to on-line and sync perform i am losing my server side changes and finally data in transaction doc is as client pouchdb.
here i am losing server side data. so what is good approach or how can i solve it.
What's happening is that you have conflicts to the same document, because it is modified in one way by the server and another way by the client. One conflicting version is winning arbitrarily, and the other is losing.
You can either resolve the conflicts or (the more reasonable solution in your case) store multiple documents per user instead of one big document.
Just because you have one database per user doesn't mean you need to have one document per user. :) E.g your docs could be:
{_id: "Tran_1", status: "Pending"}
{_id: "Tran_2", status: "Pending"}
// etc.
These documents would be created once on the client and updated once on the server. No possibility of conflicts. Piece of cake!
Related
I am building a platform, where there is a master DB which holds all the user data, this db is used when user tries to login and after successful login application should fetch data from respective user DB. We are using MongoDB, mongoose driver and epxpress framework. Please guide
To answer your question:
You can use createConnection() to create multiple connections to different databases.
However, unless you'll only have a handful of users & databases (maybe 10, maybe more), this will very likely not scale very well, since mongoose is not made for this kind of usage. I'd rather advise to either combine the databases into a single one or if you'll have a lot of data or security concerns, create a multi-tenant system hosting an app-instance connected to each database.
I want to use Couchdb to create a offline first app, where users can add documents.
Only the user who created a document should be able to change it, otherwise it should only be readable. For this i wanted to use the "peruser" mechanism of couchdb and replicate these documents into a main database where everyone can read.
Is it possible to automatically get the replication and other configurations (like design documents) configured when the database is created by the couch_peruser options?
I found a possible way myself:
add a validation function to the main database to deny writes (http://docs.couchdb.org/en/2.1.1/ddocs/ddocs.html#vdufun)
use _db_updates endpoint to monitor database creation (http://docs.couchdb.org/en/2.1.1/api/server/common.html#db-updates)
create a _replicator document to set up a continuous replication from userdb to main db (http://docs.couchdb.org/en/2.1.1/replication/replicator.html)
One thing to look about is that maintaining a lot of continuous replications requires a lot of system resources.
Another way is to create authorships with design documents. With this aproach we don't need to maintain replications to the main database, because every entry can be hold in one database (main database in my case).
http://guide.couchdb.org/draft/validation.html#authorship
I'm using PouchDB + CouchDB to store and sync data in an angular app currently in development. Data is stored per user and contains things such as user authorities/settings, recently viewed content and cart items.
Currently, I have a single CouchDB database that contains a doc for each user. While this structure works well for quickly retrieving user-specific data, it's logically flawed because all user docs are synced to any device that accesses the app. In other words, I ultimately only need the currently logged in user's data to sync.
So, my question is, should I create a Couch database for each user instead of using a single database with a doc for each user? Or is there a better way to go about this?
If you look at the pouchdb-authentication plugin you'll see that you can store metadata for a user in the _user database. That might be all you need.
I have a Node.JS server with a Mondodb database. Multiple clients use this same database, and each client has his own collection. The collections are named by the id of the client.
Since every client uses a different name for his data, when a new client connects to the server, the first operation he does on the database will create a new collection for him.
I need all the collections to have a specific index. Is there a way to automatically create this index for every new collection?
No, there is no such command.
But don't be afraid to call createIndex too often. The documentation guarantees that when an index with the same settings already exists, nothing will happen. So you can attach it to some common database operations executed by new users. It's no big deal when it gets called more than once.
To highlight this behavior, the method used to be called ensureIndex, but that name is deprecated.
By the way: Having a different collection for every client is a quite unusual architecture. It has some drawbacks, like the problem with indexes and other collection-level configuration you already discovered, but also others like being unable to do any queries which use data from more than one client. With the default storage engine, there is the advantage that clients can not lock each other with collection-wide locks, but when you use the WiredTiger engine, that advantage is obsolete because WiredTiger locks only on document level.
A more conventional approach is to have one collection for all users and have a field in each document which says which user owns the document and which is part of all indexes used by user-specific queries.
I'm using the CouchDB permission system with per-db-and-user access rights. Each DB represents an app, which are being displayed in a home-screen-like overview and in other places. I need an efficient way to make CouchDB tell me whether a user has access to a db or not - for example a GET /_all_dbs that only returns the DBs for which current user has access. Polling a view or document turns out to be too slow once there are more than a dozen or so apps to display on one page, although I could still tune a view poll with limit=1. Isn't there a better way though?
Query the _security document of the database.
curl http://localhost:5984/db_name/_security
{"admins":{"names":["dbadmin"],"roles":["reader"]},"members":{"names":[],"roles":[]}}
For every database that has admins/users couchdb has a creates a special document called _security that holds a list of all the users for that database. You can make a curl request to that document and get an array that will give you all the admins and members for that database.
Edit
You know your application best but here is a strategy that I think could be helpful? Every couchdb user is stored in the _users database. It is just like any other database. You can create a view on it and then query it. You can even add additional fields to the documents to help with querying. How about when you create a user on a database you update the corresponding document in the _users database as well.
Now if you call _users/_all_docs?include_docs=true you get a list of users along with the databases they have access to. One request and you have everything you need.