Команда ReQL: update
Синтаксис команды
table.update(object | function[, {durability: "hard", returnChanges: false, nonAtomic: false, ignoreWriteHook: false}]) → object
selection.update(object | function[, {durability: "hard", returnChanges: false, nonAtomic: false, ignoreWriteHook: false}]) → object
singleSelection.update(object | function[, {durability: "hard", returnChanges: false, nonAtomic: false, ignoreWriteHook: false}]) → object
Описание
Обновляет JSON-документы в таблице. Принимает JSON-документ, выражение ReQL или их комбинацию.
Необязательные аргументы:
-
durability: возможные значения —hardиsoft. Этот параметр переопределит параметр устойчивости к сбоям таблицы или запроса (настроенный в run). В режиме мягкой устойчивости RethinkDB подтвердит запись сразу после ее получения, но перед ее записью на диск. -
returnChanges:-
true: возвращает массивchanges, содержащий объектыold_val/new_val, описывающие внесенные изменения, включающий только документы, которые были фактически обновлены. -
false: не возвращает массивchanges(по умолчанию). -
"always": ведет себя какtrue, но включает все документы, которые команда пыталась обновить, независимо от того, была ли операция обновления успешной. (Это было поведениеtrueдо версии 2.0.)
-
-
nonAtomic: если установлено значениеtrue, выполняет обновление и распределяет результат репликам неатомарно. Этот флаг необходим для выполнения недетерминированных обновлений, таких как те, которые требуют чтения данных из другой таблицы. -
ignoreWriteHook: Еслиtrue, и если у пользователя есть разрешение на конфигурацию, игнорирует любой write hook при выполнении обновления.
Обновление возвращает объект, содержащий следующие атрибуты:
-
replaced: количество документов, которые были обновлены. -
unchanged: количество документов, которые были бы изменены, но новое значение было таким же, как старое. -
skipped: количество документов, которые были пропущены, потому что документ не существовал. -
errors: количество ошибок, возникших во время выполнения обновления. -
first_error: Если возникли ошибки, содержит текст первой ошибки. -
deletedиinserted: 0 для операции обновления. -
changes: еслиreturnChangesустановлено вtrue, это будет массив объектов, по одному для каждого объекта, затронутого операциейupdate. Каждый объект будет иметь два ключа:{new_val: <new value>, old_val: <old value>}.
Операции записи RethinkDB будут выбрасывать исключения только в том случае, если ошибки возникнут до каких-либо записей. Другие ошибки будут перечислены в
first_error, аerrorsбудет установлено на значение, отличное от нуля. Для правильной обработки ошибок с этим термином код должен обрабатывать как исключения, так и проверять значение возвратаerrors!
Пример: Обновить статус поста с id от 1 до published.
r.table("posts").get(1).update({status: "published"}).run(conn, callback)
Пример: Обновить статус всех постов до published.
r.table("posts").update({status: "published"}).run(conn, callback)
Пример: Обновить статус всех постов, написанных Уильямом.
r.table("posts").filter({author: "William"}).update({status: "published"}).run(conn, callback)
Обратите внимание, что
filter,getAllи аналогичные операции не выполняются атомарно сupdate. Подробности см. в разделе Гарантии согласованности. Также см. пример условных обновлений ниже для решения с использованиемbranchвupdateпункте.
Пример: Увеличить поле view поста с id от 1. Этот запрос сгенерирует ошибку, если поле views не существует.
r.table("posts").get(1).update({
views: r.row("views").add(1)
}).run(conn, callback)
Пример: Увеличить поле view поста с id от 1. Если поле views не существует, оно будет установлено в 0.
r.table("posts").get(1).update({
views: r.row("views").add(1).default(0)
}).run(conn, callback)
Пример: Выполнить условное обновление.
Если у поста более 100 просмотров, установить type поста на hot, иначе установить на normal.
r.table("posts").get(1).update(function(post) {
return r.branch(
post("views").gt(100),
{type: "hot"},
{type: "normal"}
)
}).run(conn, callback)
Пример: Обновить поле numComments результатом подзапроса. Поскольку это обновление не является атомарным, вы должны передать флаг nonAtomic.
r.table("posts").get(1).update({
numComments: r.table("comments").filter({idPost: 1}).count()
}, {
nonAtomic: true
}).run(conn, callback)
Если вы забудете указать флаг nonAtomic , вы получите ReqlRuntimeError:
ReqlRuntimeError: Could not prove function deterministic. Maybe you want to use the non_atomic flag?
Пример: Обновить поле numComments случайным значением от 0 до 100. Это обновление нельзя доказать детерминированным из-за r.js (и на самом деле оно таковым не является), поэтому вы должны передать флаг nonAtomic.
r.table("posts").get(1).update({
num_comments: r.js("Math.floor(Math.random()*100)")
}, {
nonAtomic: true
}).run(conn, callback)
Пример: Обновить статус поста с id от 1 с мягкой устойчивостью.
r.table("posts").get(1).update({status: "published"}, {durability: "soft"}).run(conn, callback)
Пример: Увеличить поле views и вернуть значения документа до и после операции обновления.
r.table("posts").get(1).update({
views: r.row("views").add(1)
}, {
returnChanges: true
}).run(conn, callback)
Результат теперь будет содержать поле changes:
{
deleted: 0,
errors: 0,
inserted: 0,
changes: [
{
new_val: {
id: 1,
author: "Julius_Caesar",
title: "Commentarii de Bello Gallico",
content: "Aleas jacta est",
views: 207
},
old_val: {
id: 1,
author: "Julius_Caesar",
title: "Commentarii de Bello Gallico",
content: "Aleas jacta est",
views: 206
}
}
],
replaced: 1,
skipped: 0,
unchanged: 0
}
Обновление вложенных полей
Команда update поддерживает синтаксис вложенных полей RethinkDB, чтобы обновлять поддокументы. Представьте таблицу пользователей с контактной информацией в формате:
{
id: 10001,
name: "Bob Smith",
contact: {
phone: {
work: "408-555-1212",
home: "408-555-1213",
cell: "408-555-1214"
},
email: {
work: "bob@smith.com",
home: "bobsmith@example.com",
other: "bobbys@moosecall.net"
},
im: {
skype: "Bob Smith",
aim: "bobmoose",
icq: "nobodyremembersicqnumbers"
}
},
notes: [
{
date: r.time(2014,1,1,'Z'),
from: "John Doe",
subject: "My name is even more boring than Bob's"
},
{
date: r.time(2014,2,2,'Z'),
from: "Bob Smith Sr",
subject: "Happy Second of February"
}
]
}
Пример: Обновить номер мобильного телефона Боба Смита.
r.table("users").get(10001).update(
{contact: {phone: {cell: "408-555-4242"}}}
).run(conn, callback)
Пример: Добавить другую заметку в запись Боба Смита.
var newNote = {
date: r.now(),
from: "Inigo Montoya",
subject: "You killed my father"
};
r.table("users").get(10001).update(
{notes: r.row("notes").append(newNote)}
).run(conn, callback)
Это приведет к ошибке, если поле notes не существует в документе. Чтобы выполнить это как «upsert» (обновить или вставить), используйте команду default, чтобы убедиться, что поле инициализировано как пустой список.
r.table("users").get(10001).update(
{notes: r.row("notes").default([]).append(newNote)}
).run(conn, callback)
Пример: Отправить сообщение каждому пользователю с номером ICQ.
var icqNote = {
date: r.now(),
from: "Admin",
subject: "Welcome to the future"
};
r.table("users").filter(
r.row.hasFields({contact: {im: "icq"}})
).update(
{notes: r.row("notes").append(icqNote)}
).run(conn, callback)
Пример: Заменить все записи IM Боба. Обычно update объединяет вложенные документы; чтобы заменить весь документ "im", используйте команду literal.
r.table('users').get(10001).update(
{contact: {im: r.literal({aim: "themoosemeister"})}}
).run(conn, callback)
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/javascript/update/