flen
flen

Reputation: 2386

CouchDB 2.0 - How to autoincrement keys in a View?

In CouchDB 2.0, I'm trying to create an ordered list as the keys from a View, but it doesn't work.

My code for the View document:

var i = 0;
function (doc) {
  if (doc.type === "comment") {    
    emit(i++, doc.webpages);
  }
}

The result is that all keys are equal to 0. How can I make it so that each document gets an autoincremented key?
Thanks!

Upvotes: 1

Views: 298

Answers (1)

sarwar
sarwar

Reputation: 2845

A sequential ID probably isn't the best choice for most real applications. For example, if you were to build a commenting system I would approach it like this (there's a similar example in the couch docs):

Comments would be docs with a structure like this:

{
    "_id": "comment_id",
     "parent":"comment_id, or article_id if a top level comment"
     "timestamp" : "iso datetime populated by the server",
     "user_id": "the person who wrote the comment",
     "content": "content of the comment"
}

To display all the top level comments of a given parent (either article or parent comment), you could use a view like this:

def function(doc){
  emit([doc.parent, doc.timestamp, doc.user_id], doc._id)
}

To query this efficiently, you'd could use the following query options to grab the first twenty:

{
    "startkey": ["parent_id"],
    "endkey": ["parent_id", {}],
    "limit": 20,
    "skip": 0,
    "include_docs": true
}

The comments will automatically be sorted by the date they were posted because the view is ordered by [parent, datetime, and then user]. You don't have the pass a value for anything other than parent with your key for benefit from this.

Another thing of note is by not passing the content of the comment to the view and instead using include_docs, your index will remain as slim as possible.

To expand on this:

  • If you want to show replies to a base comment, you can just change the start and end keys to that comment's id.
  • If you want to show the next 20 comments, just change skip to 20.
  • If you want more comments shown initially, just up the limit value.

In answer to your comment, if you had an array or parents in your document like:

"parents" : ["a100", "a101", "a102"]

Everything else would remain the same, except you would emit a row for each parent.

def function(doc){
  doc.parents.map( function (parent){
    emit([doc.parent, doc.timestamp, doc.user_id], doc._id)
  });
}

Upvotes: 1

Related Questions