Top.Mail.Ru
space_object:update() | Tarantool
 

space_object:update()

space_object:update()

object space_object
space_object:update(key, {{operator, field_identifier, value}, ...})

Обновление кортежа.

Функция update поддерживает операции над полями — присваивание, арифметические операции (если поле числовое), вырезание и вставку фрагментов поля, удаление или вставку поля. Несколько операций можно объединить в отдельный запрос обновления, и в таком случае они будут выполняться атомарно и последовательно. Для каждой операции необходимо указать идентификатор поля, как правило числовой. При выполнении нескольких операций номер поля для каждой операции принимается относительно последнего состояния кортежа, то есть как если бы уже были выполнены все предыдущие операции в обновлении с несколькими операциями. Другими словами, всегда лучше объединить несколько вызовов update в один без изменений семантики.

Возможные операторы:

  • + для сложения; значения должны быть числовыми, например, unsigned или decimal
  • - для вычитания; значения должны быть числовыми
  • & для операции побитового И; значения должны быть числовыми типа unsigned
  • | для операции побитового ИЛИ; значения должны быть числовыми типа unsigned
  • ^ для операции побитового исключающего ИЛИ; значения должны быть числовыми типа unsigned
  • : для разделения строк.
  • ! для вставки нового поля.
  • # для удаления.
  • = для присваивания.

Возможные операторы:

  • Положительный номер позиции поля. Первое поле — 1, второе — 2 и так далее.
  • Отрицательный номер позиции поля. Последнее поле — −1, предпоследнее — −2 и так далее. Другими словами: (#tuple + отрицательный номер позиции поля + 1).
  • Имя. Если спейс был отформатирован с помощью space_object:format(), здесь может быть строка с именем поля.
Параметры:
  • space_object (space_object) – ссылка на объект
  • key (scalar/table) – значения поля первичного ключа, которые должны возвращаться в виде Lua-таблицы, если ключ составной
  • operator (string) – тип операции, представленный строкой
  • field_identifier (number-or-string) – к какому полю применяется операция.
  • value (lua_value) – какое значение применяется
возвращает:
  • обновленный кортеж
  • nil, если ключ не найден
тип возвращаемого значения:
 

кортеж или nil

Возможные ошибки: нельзя изменять поле первичного ключа.

Факторы сложности Размер индекса, тип индекса, количество индексов, к которым получен доступ, настройки журнала упреждающей записи (WAL).

Таким образом, в инструкции:

s:update(44, {{'+', 1, 55 }, {'=', 3, 'x'}})

значение первичного ключа равно 44, заданы операторы '+' и '=', что означает прибавление значение к полю, а затем присваивание значения полю, первое затронутое поле – это поле 1, к нему прибавляется значение 55, второе затронутое поле – это поле 3, ему присваивается значение 'x'.

Пример:

Предположим, что изначально есть спейс под названием tester с первичным индексом, тип которого – unsigned. Есть один кортеж с полем №1 field[1] = 999 и полем №2 field[2] = 'A'.

В обновлении:
box.space.tester:update(999, {{'=', 2, 'B'}})
Первый аргумент – это tester, то есть обновление происходит в спейсе tester. Второй аргумент – 999, то есть затронутый кортеж определяется по значению первичного ключа = 999. Третий аргумент – =, то есть будет одна операция – присваивание полю. Четвертый аргумент – 2, то есть будет затронуто поле №2 field[2]. Пятый аргумент – 'B', то есть содержимое field[2] изменится на 'B'. Таким образом, после данного обновления field[1] = 999, а field[2] = 'B'.

В обновлении:
box.space.tester:update({999}, {{'=', 2, 'B'}})
Аргументы повторяются за исключением того, что ключ передается в виде Lua-таблицы (в фигурных скобках). В этом нет необходимости, если первичный ключ содержит только одно поле, но было бы необходимо, если бы в первичном ключе было больше одного поля. Таким образом, после данного обновления field[1] = 999, а field[2] = 'B' (без изменений).

В обновлении:
box.space.tester:update({999}, {{'=', 3, 1}})
Аргументы повторяются за исключением того, что четвертым аргументом будет 3, то есть будет затронуто поле №3 field[3]. Ничего страшного, что до этого поле field[3] не существовало. Оно добавится. Таким образом, после данного обновления field[1] = 999, field[2] = 'B', field[3] = 1.

В обновлении:
box.space.tester:update({999}, {{'+', 3, 1}})
Аргументы повторяются за исключением того, что третьим аргументом будет '+', то есть будет операция добавления, а не присваивания. Поскольку``field[3]`` ранее содержало значение 1, это означает, что к 1 прибавится 1. Таким образом, после данного обновления field[1] = 999, field[2] = 'B', field[3] = 2.

В обновлении:
box.space.tester:update({999}, {{'|', 3, 1}, {'=', 2, 'C'}})
Основная идея состоит в том, чтобы изменить одновременно два поля. Форматами будут '|' и =, то есть имеем две операции: ИЛИ и присваивание. Четвертый и пятый аргументы означают, что над полем field[3] проводится операция ИЛИ со значением 1. Седьмой и восьмой аргументы означают, что полю field[2] присваивается 'C'. Таким образом, после данного обновления field[1] = 999, field[2] = 'C', field[3] = 3.

В обновлении:
box.space.tester:update({999}, {{'#', 2, 1}, {'-', 2, 3}})
Основная идея состоит в том, чтобы удалить поле field[2], а затем вычесть 3 из field[3]. Но после удаления, произойдет перенумерация, поэтому поле field[3] становится field[2] до того, как мы вычтем из него 3, вот почему седьмым аргументом будет 2, а не 3. Таким образом, после данного обновления field[1] = 999, field[2] = 0.

В обновлении:
box.space.tester:update({999}, {{'=', 2, 'XYZ'}})
Создаем длинную строку, чтобы в следующем примере сработало разделение. Таким образом, после данного обновления field[1] = 999, field[2] = 'XYZ'.

В обновлении:
box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}})
Третьим аргументом будет ':', то есть это пример разделения. Четвертым аргументом будет 2, поскольку изменение произойдет в поле field[2]. Пятым аргументом будет 2, поскольку удаление начнется со второго байта. Шестым аргументом будет 1, количество удаляемых байтов – 1. Седьмым аргументом будет '!!', поскольку в данном положении будет добавляться '!!'. Таким образом, после данного обновления field[1] = 999, field[2] = 'X!!Z'.

Для получения дополнительной информации о сценариях использования и типичных ошибках, см. Пример: использование операций с данными далее в разделе.

Начиная с версии Tarantool 2.3 кортеж можно обновить с помощью JSON-путей.