Posted by Lena Herrmann Tue, 22 Dec 2009 17:37:00 GMT

For the couchapp I'm writing, I recently wanted to do a bulk delete operation with CouchDB, but found very little about it on the web. I don't know if my approach is the best way to go, but well, it works - if you know a better way, I'm happy to learn about it.

In the file jquery.couch.js that comes with CouchDB there are a couple of convenience methods to help you dealing with the database, documents and views. There is a method for deletion too (removeDoc), but it only can handle one document at a time. In the style of bulkSave, I added a bulkRemove method:

bulkRemove: function(docs, options){
  docs.docs = $.each(docs.docs, function(i, doc){doc._deleted = true});
  $.extend(options, {successStatus: 201});
  ajax({
      type: "POST",
      contentType: "application/json",
      dataType: "json", 
      data: toJSON(docs),
      url: this.uri + "_bulk_docs" + encodeOptions(options)
    },
    options,
    "The documents could not be deleted"
  );
},

In here I add the attribute "_deleted = true" to every document I want to delete, and then I do a bulk update with the documents. That's it.

This is one possible use case: In the delete action of my controller I first fetch an array with the post and its comments from the couch (how to do this see below), and then I call the bulkRemove action on that array.

couchapp.design.view('post_with_comments', {
  startkey: [params['id']],
  endkey: [params['id'], {}],
  success: function(json) {
    if (json.rows.length > 0) { 
      var post_and_comments = json.rows.map(function(row) {return row.value}); 
      couchapp.db.bulkRemove({docs: post_and_comments}, {
        success: function() {
          flash = {message: 'Post deleted.', type: 'notice'}
          redirect('#/outlines', flash);
        },
        error: function(response_code, msg) {
          flash = {message: 'Error deleting post: ' + msg, type: 'error'};
        }
      });
    }      
  }
});

Note that the "flash" object I'm using is my own Sammy.js implementation of a Rails-like flash to show a message after a redirect. Maybe I'll share that in another blog post.

As a bonus, this is the view I'm using to retrieve a post and its comments in one request. I'm following the pattern Christopher Lenz is recommending in his article on CouchDB Joins.

function(doc) {
  if (doc.type == "Post") {
    emit([doc._id, 0], doc);
  } else if (doc.type == "Comment") {
    emit([doc.post_id, 1, Date.parse(doc.created_at)], doc);
  }
}

When you call this view with

startkey: [params['id']],
endkey: [params['id'], {}]

you get an array with the post as the first element, and then all the comments that have the post's ID as post_id.

This can of course also be used for things other than deleting: to show all the comments for a post, I get the array's first element and extract the title and content. Then I remove it from the array with

json.rows.splice(0,1);        

You now have an array with only the post's comments and you can display them somehow.

2 comments |

Trackbacks

Use the following link to trackback from your own site:
http://lenaherrmann.net/trackbacks?article_id=8

Comments

Leave a comment

  1. Avatar
    Jan
    about 1 hour later:

    Cool stuffs! Can you open an issue on the CouchDB bugtracker so we can add the method?

    https://issues.apache.org/jira/browse/COUCHDB

    Cheers

    Jan

  2. Avatar
    Lena
    12 days later:

Leave a comment