Spec-Zone.ru › RethinkDB javascript

Команда 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)

Связанные команды

  • insert
  • replace
  • delete

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/javascript/update/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API