RethinkDB: как сделать реальный upsert - вставить новый документ при сбое обновления?

Я хочу вставить новый документ при сбое обновления - есть ли способ сделать это? Теперь RethinkDB позволяет мне обновлять документ только при сбое вставки с помощью {upsert: true} в команде вставки.


person La Faulx    schedule 14.01.2014    source источник


Ответы (1)


Вы можете использовать replace с ветвью и явным слиянием.

replace похож на update, за исключением того, что он полностью заменяет документ, а не сливается с ним. Следующие эквивалентны (в коде Ruby):

table.get(id).update{|row| {a: row['a']+1}}
table.get(id).replace{|row| row.merge({a: row['a']+1})}

Итак, если вы хотите выполнить «обновление» или вставить строку, если строки нет, вы можете сделать это:

table.get(id).replace {|row|
  r.branch(
    row.eq(nil),
    INSERT_OBJECT,
    row.merge(UPDATE_OBJECT))
}
person mlucy    schedule 16.01.2014
comment
Как я понимаю, таблица (что-то) возвращает все записи из таблицы, затем вы проверяете, является ли запись нулевой - как она может быть нулевой? Если я пытаюсь что-то выполнить после того, как запрос get вернул null, то Rethink выдает ошибку - в этом проблема - person La Faulx; 22.01.2014
comment
являются ли INSERT_OBJECT и UPDATE_OBJECT реальными вещами или просто заполнителями? :) действительно ли они должны быть r.db().table().insert({}) и row.merge({field1: , field2:, field3: и т.д...})? - person Shai Mishali; 26.06.2015
comment
Они являются заполнителями для объектов. Таким образом, пример запроса будет r.table('test').get(0).replace {|row| r.branch(row.eq(nil), {id: 0, a: 0}, row.merge({a: 0})) } - person mlucy; 26.06.2015
comment
Есть ли способ сделать это чистым способом? Я хотел бы сделать то же самое, что и Redis redis.io/commands/zincrby, где я хочу увеличить счетчик или добавить документ со счетчиком 1, если он не существует. Я не вижу на примере, как это будет работать. - person Astronaut; 01.11.2016