3

Basic problem

I have some large, but logically organised documents - and would like to perform updates on just a sub-section of an individual document.

Example

Given this simple document:

_id: 123456,
_rev: 3242342,
name: 'Stephen',
type: 'Person',
hobbies: [ 'sky-diving' ]

In my application I might have an addHobbies method, that would use a view that just retrieves:

_id: 123456,
_rev: 3242342,
hobbies: [ 'sky-diving' ]

So that it can then add an additional hobby to the hobbies array, and then PUT just this sub-set of data back to the document.

Question

As I understand it, CouchDB [1.2] does not allow partial updates like this, and so I believe it would be necessary to grab the whole document during the save operation, merge my changes, then PUT the whole document back on every single save.

  • Is there another way of doing this (am I wrong about CouchDB's capabilities)?
  • Are there any libraries (I'm using express on node.js) to handle this kind of operation?
Community
  • 1
  • 1
isNaN1247
  • 17,793
  • 12
  • 71
  • 118

2 Answers2

4

You are correct. That is, in fact, what document database means: check-outs and check-ins.

You can create (or use) shim code to simulate what you want, letting you focus on the important parts. On the server side, you can use update functions.

There are many solutions on the client side.

cradle.js will give you fake partials updates with the merge method.

If you only want to update one or more attributes, and leave the others untouched, you can use the merge() method:

db.merge('luke', {jedi: true}, function (err, res) {
    // Luke is now a jedi,
    // but remains on the dark side of the force.
});

https://github.com/cloudhead/cradle/

Related, and also for Node.js is Transaction for performing arbitrary atomic transactions on CouchDB documents.

JasonSmith
  • 72,674
  • 22
  • 123
  • 149
Pickels
  • 33,902
  • 26
  • 118
  • 178
  • 2
    +1. I took the liberty of fleshing things out, linking to a related tool (which I maintain) and also to the official documentation of server-side partial updates. – JasonSmith May 14 '12 at 00:03
  • Thank you both for your input. "Update functions" are the ideal solution that I was after... can't believe I missed them in the docs. Thanks very much! I personally never really got on with crade and preferred [nano](https://github.com/dscape/nano) instead – isNaN1247 May 14 '12 at 07:28
  • +1 for a good, detailed answer, but mostly for the awesome example ^^ – Hyddan Sep 14 '13 at 10:25
0

I would say that cradle is currently missing a real partial update feature, which would also support updating a path to a key inside the field value's JSON data, like Apache demonstrates here, rather than being limited to updating only a single key in a document, like the db.merge method.

In fact, looking at the cradle source, I see that there is a Database.prototype.update method (in lib/cradle/document.js), but this method doesn't seem to be documented.

It would be elegant of this could be made an integral part of cradle, eliminating the need to do separate requests to CouchDB view's updates only for partial updates.

Mattijs
  • 1,909
  • 3
  • 19
  • 28