none
none

Reputation: 67

Examples of how to structure CouchDB

I'm looking for a good examples/practices on how to store and structure the data in CouchDB.

Something a bit more complex than the blog app in the definitive guide.

Let's imagine an application like Stack Overflow.

Upvotes: 4

Views: 3050

Answers (4)

philn5d
philn5d

Reputation: 634

The model exemplified in http://www.cmlenz.net/archives/2007/10/couchdb-joins was helpful in understanding structure, but I do have one comment on the approach of using the blog topic for the doc id. If two users have the same blog title, this would cause a conflict. I'm new to couchdb, but it seems as if the doc id and the doc title should be separate despite the challenge of being able to load a blog with /blogName. Can that still be accomplished with a structure
{_id:6377738426gdjjsb,_rev:1-hsusubsvh6377,title:blogName,authorName:shakespeareND5}

Upvotes: 0

AndrewHenderson
AndrewHenderson

Reputation: 4972

I suggest you store the various parts (users, questions, answers, comments, tags, votes) as separate documents in one database.

No. Do not store these in separate databases. You will lose the power of views and have to make an exponential amount of HTTP requests to gather the data.

--

Check out http://www.cmlenz.net/archives/2007/10/couchdb-joins. It really shed light on the subject for me. Credit to Costa for sharing link in another question.

While the article uses the ubiquitous blog example, I believe Approach #2 with "View Collation" is what you want.

Documents that are children of another document will be linked by the parent's "_id" attribute. Also, you'll give your documents a "type" attribute for the purposes of ordering them when returned in a view. For example:

function(doc) {
  if (doc.type == "post") {
    map([doc._id, 0], doc);
  } else if (doc.type == "comment") {
    map([doc.post, 1], doc);
  }
}

What you'll have returned is this:

{
 "total_rows": 5, "offset": 0, "rows": [{
  "id": "myslug",
  "key": ["myslug", 0],
  "value": {...}
}, {
  "id": "ABCDEF",
  "key": ["myslug", 1],
  "value": {...}
}, {
  "id": "DEFABC",
  "key": ["myslug", 1],
  "value": {...}
}, {
  "id": "other_slug",
  "key": ["other_slug", 0],
  "value": {...}
}, {
  "id": "CDEFAB",
  "key": ["other_slug", 1],
  "value": {...}
}]
}

You now have all the data, parent and children returned in one HTTP request. Plus, you can CRUD on these documents directly through your REST API. Which is exactly what you want, in my opinion.

You can apply the same approach to anything that has a one-to-many or many-to-one relationship.

Hope this helps!

Upvotes: 1

Costa Michailidis
Costa Michailidis

Reputation: 8178

With Regard to doing 'joins' in couchdb:

Actually it might make more sense not to duplicate data. Here's an example of a view I created in couchdb: http://wamoyo.iriscouch.com/_utils/database.html?ideageneration/_design/IdeaGeneration/_view/challengesAndIdeas

This simple app let's people enter challenges, and then let's them collect ideas on how to resolve those challenges. It translates quite well into the blog example: Challenges would be the blog posts, and ideas would be the comments that fit under each blog post.

I've posted this up in full detail to another question here: Couch DB Join operations like RDBMS

With regard to structuring apps in couchdb, Jason I'm playing with the same question. CouchDB offers lots of flexibility, so I'm not quite sure if I should use shows and lists to display data, or just write client side code to do that, maybe with backbone, and then just use couchdb views to supply the model. Let me know what you come up with, I'd be very curious.

Upvotes: 0

SingleNegationElimination
SingleNegationElimination

Reputation: 156188

Concepts that work well for structuring data in Relational databases are just as valid for document storage databases. The only thing that really changes is that queries that would normally be done with a join on a relational database are usually cumbersome in a NoSQL database. This means that one to many relationships usually resolved with a join on a RDBMs will usually involve much more denormalization on a NoSQL db. In a typical example of a one to many relationship, like Blog Posts and Comments on that post, instead of having a foreign key in the comment to the post, you would actually duplicate some data from the post into the comment to avoid having an extra query, and you would also keep a list of comment ID's (and maybe the 10 most recent comment bodies as well) in the post.

Upvotes: 2

Related Questions