Полезен ли RethinkDB для частичного обновления документов json в соответствии с rfc6902?

Пожалуйста, поделитесь своим опытом частичного обновления документа JSON. Сейчас я храню свои документы JSON в MongoDB, который выглядит следующим образом:

{
  id: ObjectId(507f191e810c19729de860ea),
  title: 'Sterling Archer',    
  comments: [
    {text: 'Comment text', tags: ['tag1', 'tag2', 'tag3']},
    {text: 'Comment test', tags: ['tag2', 'tag5']}
  ]  
}

Мне нужно часто обновлять документы, используя спецификацию rfc6902. Теперь я делаю это неоптимизированным способом, который выглядит следующим образом (в этом примере я использую модуль nodejs/express/mongoose и fast-json-patch):

var jsonpatch = require('fast-json-patch');

app.patch('/document/:id', function (req, res, next) {
   var document_id = req.params.id;

   // req.body.patch: { "op": "add", "path": "/comments/2", "value":  {text: 'Comment test3', tags: ['tag4']}" }
   var patches = req.body.patch; 

   // find document
   Document.findById(document_id, function (err, document) {
       // Applying patches
       jsonpatch.apply(document, patches);

       // Update whole document in MongoDB
       Document.update({_id: document_id}, document, function (err) {
           return res.status(200).send(); 
       });
   });
});

Это неоптимальный подход к исправлению документов из-за двух запросов в MongoDB и замены всего документа. Поэтому я ищу оптимизированный подход и хочу попробовать RethinkDB для этой задачи. Можете ли вы помочь мне проверить возможность атомарного обновления документа с помощью одного запроса с RethinkDB? Или я должен искать другой способ решения моей проблемы?

Поделитесь своим опытом частичного обновления документа JSON.


person Erik    schedule 24.09.2014    source источник


Ответы (1)


Вам нужен всего один запрос в RethinkDB. Предположим, вы хотите обновить документ с идентификатором 1 со значениями {foo: 1, bar: 2} и увеличить поле «count», вы должны сделать

r.table("data").get(1).update(function(doc) {
    return doc.merge({foo: 1, bar:2, count: doc("count").add(1) })
})

Хотя для этого обновления требуется уникальный запрос, будет обновлен весь документ. Если у вас есть большие документы, вы можете разделить их на несколько таблиц и позже выполнить объединение для извлечения данных. Вам может быть интересно прочитать эту статью о моделировании данных: http://www.rethinkdb.com/docs/data-modeling/

person neumino    schedule 24.09.2014
comment
Спасибо за ответ. К сожалению, я не могу разделить документ на несколько таблиц. RethinkDB не нравятся большие вложенные документы JSON? - person Erik; 24.09.2014
comment
Это зависит от того, что вы называете большим, и от вашей рабочей нагрузки. При этом должно работать нормально. RethinkDB особенно эффективен на SSD. Но я полагаю, что единственный реальный ответ — попробовать свою рабочую нагрузку? - person neumino; 24.09.2014
comment
Спасибо. Есть ли у вас опыт использования частичного JSON в ваших проектах? - person Erik; 24.09.2014
comment
(Примечание: я инженер RethinkDB). Насколько я знаю, почти все делают частичное обновление с помощью RethinkDB, потому что это более эффективно и к чему мы привыкли (похоже на оператор SQL UPDATE). Лично я использую его в некоторых личных проектах (например, для увеличения статистики для журналов), и он работает как шарм. - person neumino; 25.09.2014
comment
Спасибо за ответ. Предоставленный вами фрагмент кода выглядит хорошо. Я попытаюсь использовать этот, но не понимаю, как мне построить запрос для move patch: [{ "op": "move", "from": "/foo/waldo", "path": "/qux/thud" }]. Можете ли вы предоставить пример кода для RethingDB, пожалуйста? - person Erik; 25.09.2014
comment
r.table(data).get(idValue).merge({/qux/thud: r.row(/foo/waldo)}).without(/foo/waldo) - person neumino; 25.09.2014
comment
@neumino в вашем комментарии предполагается, что /foo/waldo является ключом, но это не так, как это работает в JSONPatch. Это указатель JSON (rfc6901) на waldo в { foo: { waldo: 'value' }}. Может ли RethinkDB справиться с этим? - person Matt Harrison; 12.03.2016