Ari
Ari

Reputation: 3669

CouchDB clears document on insert?

I'm using nano with couchDB, and I am just trying to do a simple update on a document to add a new field. For example, let's say I have a document called foo. The only field in it right now is 'bar', with some value. I then attempt to do db.insert with the code I'll post at the end, but instead of now having both fields, bar is erased, and I instead just have my new field. How can I fix this?

The code I'm using:

    dB.get('foo', function(err, body) {
        if (!err){

            if(typeof body.qwax === 'undefined'){
                dB.insert({qwax : [data], "_rev" : body._rev}, 'foo', function(err, body, header) {
                    if (err) {
                        console.log(err.message);
                        return;
                    }
                });
            }
            else{
                body.qwax.push(data);
                dB.insert({qwax : body.qwax, "_rev" : body._rev}, 'foo', function(err, body, header) {
                  if (err) {
                    console.log(err.message);
                    return;
                  }

                });
            }
        }
        else{console.log(err);}
    });

Where data is defined elsewhere.

Upvotes: 1

Views: 673

Answers (3)

AndyD
AndyD

Reputation: 5385

In nano there is an atomic function you can call to call a specific update functionon a design document: https://github.com/dscape/nano#dbatomicdesignname-updatename-docname-body-callback

Here's the usage example that is mentioned in the docs: https://github.com/dscape/nano/blob/master/tests/design/atomic.js

for example, you could create this updates attribute to your _foo design document:

updates: {
        setBar: function (doc, req) {
          var body = JSON.parse(req.body);
          doc.bar = body.bar;
          return [doc, 'OK'];
        }

You would then call this setBar update function using nano like this:

db.atomic('_foo', 'setBar', your_foo_document_id, { bar: barvalue }, function (err, headers) {
    if (err) {
      return callback(err);
    }
    ... rest of your code

Upvotes: 2

Marcin Skórzewski
Marcin Skórzewski

Reputation: 2854

You can use update handlers (wiki) in the design document for that. You simply write a JS function and instead of sending whole document again you call this function and it can make the updates "in place".

The function will get two parameters: the document to update and some data provided by from the client, and it will return in the HTTP header the new version of the updated document.

Upvotes: 0

Davorin Ruševljan
Davorin Ruševljan

Reputation: 4392

For each update you need to provide whole document, not just fields to add to the document. So you need to fetch current version of the document, add filed to it and then do the db update.

dB.insert({qwax : [data], "_rev" : body._rev, "bar" : body.bar}, 'foo', function(err, body, header) {
                if (err) {
                    console.log(err.message);
                    return;
                }
            });

Upvotes: 0

Related Questions