Arcy
Arcy

Reputation: 375

How can I do partial update or other methods to update complex documents in PouchDb?

I have a complex document like this:

    {
   "_id": "07394B10-DEB7-E703-BB97-37B694FA0877",
   "_rev": "2-9a2c5809802024a8d35cc9fbba9ea885",
   "name": "Ivrea",
   "number": "1",
   "owners": [
       {
           "name": "Ale",
           "address": "Via Ale 2",
           "gender": "Uomo",
           "type": "Assente",
           "date": "2014-08-10",
           "notes": [
               {
                   "text": "Foo",
                   "date": "2014-08-10"
               }
           ]
       }
   ]
}

how can I update it partially? Ex. only owners.name or owners.notes.date ? If I will doing a "join" with linked documents method, how can I do with this examples splitting owners and notes? thanks for your answers!

Upvotes: 2

Views: 296

Answers (1)

nlawson
nlawson

Reputation: 11620

A join does indeed seem to be your best bet, since there is no way in PouchDB to just update "part" of a document – you have to update the whole thing.

How about something like this? Let's say you have owners and cars.

var owner = {
  _id: 'owner_1', // could be 'owner_' + Math.random() or whatever
  name: 'Cookie Monster',
  type: 'owner'
};

var car = {
  _id: 'car_1', // ditto
  name: 'Mach 5',
  type: 'car',
  ownerId: 'owner_1' // Cookie Monster drives the Mach 5 :)
};

var db = new PouchDB('mydb');

db.bulkDocs([owner, car]).then(function () {
  return db.put({
    _id: '_design/owners_and_cars',
    views: {
      owners_and_cars: {
        map: function (doc) {
          if (doc.type === 'car') {
            emit(doc._id, {_id: doc.ownerId});
          }
        }.toString()
      }
    }
  }).catch(function (err) {
    if (err.status !== 409) {
      // 409 means already exists
      throw err;
    }
  });
}).then(function () {
  return db.query('owners_and_cars', {include_docs: true});
}).then(function (res) {
  console.log(JSON.stringify(res));
}).catch(function (err) { 
  /* ... */
});

This prints:

{
  "total_rows": 1,
  "offset": 0,
  "rows": [
    {
      "id": "car_1",
      "key": "car_1",
      "value": {
        "_id": "owner_1"
      },
      "doc": {
        "name": "Cookie Monster",
        "type": "owner",
        "_id": "owner_1",
        "_rev": "1-f702c1d279add84b30c6464070d8a985"
      }
    }
  ]
}

This may be slow if you have a lot of data, though, because secondary indexes are slow. In that case, you can just explicitly do an allDocs query:

db.allDocs({startkey: 'car_', endkey: 'car_\uffff'}); // finds all cars
db.allDocs({startkey: 'owner_', endkey: 'owner_\uffff'}); // finds all owners

Then you would manually do the join.

Upvotes: 1

Related Questions