space_object:update()
-
object
space_object -
space_object:update(key, {{operator, field_no, value}, ...}) Обновление кортежа.
Функция
updateподдерживает операции над полями – присваивание, арифметические операции (если поле числовое), вырезание и вставку фрагментов поля, удаление или вставку поля. Несколько операций можно объединить в отдельный запрос обновления, и в таком случае они будут выполняться атомарно и последовательно. Для каждой операции необходимо указать номер поля. Если выполняются несколько операций, то номер поля для каждой операции считается относительно последнего состояния кортежа, то есть как если бы все предыдущие операции в обновлении с несколькими операциями уже были выполнены. Другими словами, всегда лучше объединить несколько вызововupdateв один без изменений семантики.Tarantool ничего не делает, если кортеж с указанным первичным ключом не найден.
Возможные операторы:
+для сложения (значения должны быть числовыми)-для вычитания (значения должны быть числовыми)&для поразрядной операции И (значения должны быть беззнаковыми числами)|для поразрядной операции ИЛИ (значения должны быть беззнаковыми числами)^для поразрядной операции Исключающее ИЛИ (значения должны быть беззнаковыми числами):для разделения строк!для вставки#для удаления=для присваивания
Для операций
!и=номер поля может быть-1, что означает последнее поле в кортеже.Параметры: - space_object (space_object) – ссылка на объект
- key (scalar/table) – значения поля первичного ключа, которые должны возвращаться в виде Lua-таблицы, если ключ составной
- operator (string) – тип операции, представленный строкой
- field_no (number) – к какому полю применяется операция. Номер поля может быть отрицательным, что означает, что позиция рассчитывается с конца кортежа. (#кортеж + отрицательный номер поля + 1)
- value (lua_value) – какое значение применяется
возвращает: - обновленный кортеж
- nil, если ключ не найден
тип возвращаемого значения: кортеж или nil
Возможные ошибки: нельзя изменять поле первичного ключа.
Факторы сложности Размер индекса, тип индекса, количество индексов, к которым получен доступ, настройки журнала упреждающей записи (WAL).
Таким образом, в инструкции:
s:update(44, {{'+', 1, 55 }, {'=', 3, 'x'}})
значение первичного ключа равно
44, заданы операторы'+'и'=', что означает прибавление значение к полю, а затем присваивание значения полю, первое затронутое поле – это поле1, к нему прибавляется значение55, второе затронутое поле – это поле3, ему присваивается значение'x'.Пример:
Предположим, что изначально есть спейс под названием
testerс первичным индексом, тип которого –unsigned. Есть один кортеж с полем №1field[1]=999и полем №2field[2]='A'.В обновлении:
box.space.tester:update(999, {{'=', 2, 'B'}})
Первый аргумент – этоtester, то есть обновление происходит в спейсеtester. Второй аргумент –999, то есть затронутый кортеж определяется по значению первичного ключа = 999. Третий аргумент –=, то есть будет одна операция – присваивание полю. Четвертый аргумент –2, то есть будет затронуто поле №2field[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, то есть будет затронуто поле №3field[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'.Для получения дополнительной информации о сценариях использования и типичных ошибках, см. Пример: использование операций с данными далее в разделе.
-