PouchDB: обновить документ с измененным объектом

Я использую Pouchdb для создания базы данных из пользовательских данных, и я хотел бы обновить документ с измененным объектом. Например, у меня есть этот начальный объект:

var doc = {
    "_id": "test",
    "trial": 0,
    "results": [11, 22, 33]
};

Затем я изменяю его:

doc.results[doc.results.length] = 44;

Я хотел бы заменить старый документ на новый. Я попробовал эти шаги:

1/ Инициализировать PouchDB и документ

var db = new PouchDB('test');
var doc = {
    "_id": "test",
    "trial": 0,
    "results": [11, 22, 33]
};

2/ Поместить исходный документ в базу данных

db.put(doc);

3/ Изменить документ

doc.results[doc.results.length] = 44;

4/ Попробуйте обновить базу данных новым документом

db.get('test').then(function(doc) {
      return db.put(doc);
    }).then(function () {
      return db.get('test');
    }).then(function (doc) {
      console.log(doc);
    });

Но документ в базе не модифицируется.

Как я могу обновить документ с измененным объектом?

ОБНОВЛЕНИЕ:

Я не могу заставить обновление работать даже с _rev. По предложению mauritslamers я попытался включить _rev в документ:

var db = new PouchDB('test');
var doc = {
    "_id": "test",
    "_rev": 0,
    "trial": 0,
    "results": [11, 22, 33]
};

И в операторе put со следующим:

db.get('test').then(function(doc) {
      return db.put(doc, doc._rev);
    }).then(function () {
      return db.get('test');
    }).then(function (doc) {
      console.log(doc);
    });

Но это не работает.


person hhh    schedule 24.04.2015    source источник


Ответы (3)


Ваш код должен быть:

db.get('test').then(function(doc) {
      return db.put(doc); // <-- no need to include rev as the second argument
    }).then(function () {
      return db.get('test');
    }).then(function (doc) {
      console.log(doc);
    });
person nlawson    schedule 24.04.2015
comment
Спасибо, но я попробовал это в первую очередь и не могу заставить его работать: документ не обновляется. - person hhh; 25.04.2015
comment
Я вижу еще одну ошибку: вы не можете установить _rev в 0. Вы не должны пытаться установить _rev самостоятельно; база данных сгенерирует его для вас, когда вы вставите документ в первый раз. Если вы застряли, я рекомендую руководства; у них есть живые примеры, которым вы можете следовать. :) pouchdb.com/guides - person nlawson; 25.04.2015
comment
Начал пробовать без всяких _rev (см. первую часть вопроса) но не получается. Я следовал примерам руководства, но нашел только случаи, когда обновление было сделано в операторе get (изменение возраста варежек :) и оно работает), и ни одного случая, когда обновление касается самого документа. - person hhh; 25.04.2015
comment
Когда вы put(doc1), вы никогда не должны снова использовать объект doc1, потому что он не будет украшен элементом _rev. Вам нужно get(), чтобы получить новый doc2 объект. Вот почему все примеры требуют от вас put(), а затем get(). Например. на этой странице описывается обновление документа: pouchdb.com/guides/documents.html - person nlawson; 25.04.2015
comment
В качестве альтернативы, если вы хотите немного пофантазировать, вы можете использовать ответ от put, чтобы самостоятельно прикрепить _rev, но это совершенно необязательная оптимизация. Например. вот пример из наших тестов: github.com/pouchdb/pouchdb/blob/ - person nlawson; 25.04.2015
comment
Еще раз спасибо за ваше время. Я думаю, что делаю то же самое, что и пример руководства: см. 4/ моего вопроса, вы находите в нем какие-либо проблемы? Я использовал get, затем put, затем get. - person hhh; 26.04.2015
comment
Хм, очень сложно сказать, в чем проблема. Также похоже, что вы не добавляете .catch(function (err) { console.log(err); }) в свою цепочку промисов, а это означает, что ваши ошибки будут проглочены молча. - person nlawson; 26.04.2015
comment
Я добавил функцию .catch, но не получаю никаких ошибок. Кажется, что get создает новый объект doc2 только тогда, когда выполняется обновление поля doc1. Это также не работает, когда я пытаюсь сделать поддельное обновление, например db.get('test').then(function(doc) {doc.name = doc.name return db.put(doc);. Однако это работает, если я создаю второй документ и делаю db.get('test').then(function(doc) {doc.name = doc1.name return db.put(doc);. - person hhh; 26.04.2015
comment
Я нашел (грязный) способ обновить свои документы: создать еще один документ и обновить каждое поле старого. Я надеюсь, что есть более приятный способ сделать это... Я думаю, проблема в том, что return db.put(doc); в нашем коде не put глобальная переменная doc, а параметр функции, то есть старый документ... Так ли это? имеет смысл? - person hhh; 27.04.2015

Просто основываясь на вашем коде, я подозреваю, что вы не включили _rev в документ или в вызов put. Если я правильно помню, PouchDB работает так же, как CouchDB, и для успешного обновления документа потребуется номер версии.

person mauritslamers    schedule 24.04.2015
comment
Спасибо за ваш ответ. Я думаю, что вы правы в отношении причины проблемы, но я не могу заставить ее работать. Пожалуйста, посмотрите на мое обновление. - person hhh; 24.04.2015

Это похоже на проблему масштаба.

Вы использовали одно и то же имя объекта 'doc' для измененного документа (во внешней/глобальной области) и изменили его за пределами блока обещания get/put (который также имел локальную область действия 'doc, который имел приоритет над измененным объектом документа).

т.е. Вы ПОЛУЧАЛИ свой старый документ, а затем ВЕРНУЛИ его обратно... таким образом, он не изменился.

Чтобы это работало:

var db = new PouchDB('test');
var doc = {
    "_id": "test",
    "trial": 0,
    "results": [11, 22, 33]
};
db.put(doc);   // initial put

db.get('test').then(function(doc) {
      doc.results[doc.results.length] = 44;    // modify it here instead
      return db.put(doc);
}).then(function () {
      return db.get('test');
}).then(function (doc) {
      console.log(doc);
});
person Dale    schedule 07.04.2016