Can I create multiple collections per database?
Asked Answered
C

3

17

Switching from mongo to pouchdb (with Cloudant), i like the "one database per user" concept, but is there a way to create multiple collections/tables per database ?

Example

- Peter  
        - History
        - Settings
        - Friends
- John
        - History
        - Settings
        - Friends

etc...

Calamity answered 28/4, 2016 at 11:26 Comment(0)
B
27

Couchdb does not have the concept of collections. However, you can achieve similar results using type identifiers on your documents in conjunction with Couchdb views.

Type Identifiers

When you save a document in Couchdb add a field that specifies the type. For example, you would store a friend like so:

{
  _id: "XXXX",
  type: "Friend",
  first_name: "John",
  ...
}

And you would store history like this:

{
  _id: "XXXX",
  type: "History",
  url: "http://www.google.com",
  ...
}

Both of these documents would be in the same database, and if you queried all documents on that database then you would receive both.

Views

You can create views that filter on type and then query those views directly. For example, create a view to retrieve friends like so (in Cloudant you can go to add new Design Document and you can copy and paste this directly):

{
  "_id" : "_design/friends",
  "views" : {
    "all" : {
      "map" : "function(doc){ if (doc.type && doc.type == 'Friend') { emit(doc._id, doc._rev)}}"
    }
  }
}

Let's expand the map function:

function(doc) {
  if (doc.type && doc.type == "Friend") {
    emit(doc._id, doc._rev);
  }
}

Essentially this map function is saying to only associate documents to this view that have type == "Friend". Now, we can query this view and only friends will be returned:

http://SERVER/DATABASE/_design/friends/_view/all

Where friends = name of the design document and all = name of the view. Replace SERVER with your server and DATABASE with your database name.

You can find more information about views here:

https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views

Bradwell answered 28/4, 2016 at 12:50 Comment(1)
I like that idea. I'm thinking about something similar. What Do you think about the idea to have a prefix in the _id field, like "users:4711"? With that you could create reporitory like queries like findUserById(userId).Kurd
A
5

You could look into relational-pouch for something like this. Else you could do "3 databases per user." ;)

Alfalfa answered 28/4, 2016 at 20:17 Comment(0)
T
1

I may not fully understand what you need here but in general you can achieve what you describe in 3 different ways in CouchDB/Cloudant/PouchDB.

  1. Single document per person (Peter, John). Sure - if the collections are not enormous and more importantly if they are not updated by different users concurrently (or worse in different database instances) leading to conflicts then, in JSON just an element for each collection, holding an array and you can manipulate everything with just one document. Makes access a breeze.
  2. Single document per collection (Peter History, Peter Settings ect). Similar constraints, but you could create a document to hold each of these collections. Provided they will not be concurrently modified often, you would then have a document for Peter's History, and another for Peter's Settings.
  3. Single document per item. This is the finest grain approach - lots of small simple documents each containing one element (say a single History entry for Peter). The code gets slightly simpler because removing items becomes a delete and many clients can update items simultaneously, but now you depend on Views to bring all the items into a list. A view with keys [person, listName, item] for example would let you access what you want.

Generally your data schema decisions come down to concurrency. You mention PouchDB so it may be that you have a single threaded client and option 1 is nice and easy?

Tryma answered 5/5, 2016 at 15:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.