REPLACE¶
Каждая операция REPLACE
ограничена одной коллекцией, и имя коллекции не должно быть динамическим. В одном запросе AQL допускается только один оператор REPLACE
для коллекции, и за ним не могут следовать операции чтения или записи, обращающиеся к той же коллекции, операции обхода или функции AQL, которые могут читать документы.
Нельзя заменить системные атрибуты _id
, _key
и _rev
, но можно заменить атрибуты _from
и _to
.
Замена документа изменяет номер ревизии документа (атрибут _rev
) на генерируемое сервером значение.
Синтаксис¶
Для операции замены существует два синтаксиса:
REPLACE document IN collection
REPLACE keyExpression WITH document IN collection
Оба варианта могут опционально заканчиваться предложением OPTIONS { ... }
.
collection
должно содержать имя коллекции, в которой должен быть заменен документ.
document
должен быть объектом и содержать атрибуты и значения для установки. Все существующие атрибуты в хранимом документе удаляются из него и устанавливаются только предоставленные атрибуты (за исключением неизменяемых атрибутов _id
и _key
и управляемого системой атрибута _rev
). Это отличает операцию REPLACE
от операции UPDATE
, которая влияет только на атрибуты, указанные в операции, и не изменяет другие атрибуты хранимого документа.
REPLACE <document> IN <collection>
¶
При использовании первого синтаксиса объект document
должен иметь атрибут _key
с ключом документа. Существующий документ с этим ключом заменяется атрибутами, предоставленными объектом document
(за исключением системных атрибутов _id
, _key
и _rev
).
Следующий запрос заменяет документ, идентифицированный ключом my_key
в коллекции users
, устанавливая только атрибуты name
и status
. Ключ передается через атрибут _key
наряду с другими атрибутами:
1 |
|
Следующий запрос недействителен, поскольку объект не содержит атрибута _key
, и поэтому невозможно определить заменяемый документ:
1 |
|
Вы можете объединить операцию REPLACE
с циклом FOR
для определения необходимых ключевых атрибутов, как показано ниже:
1 2 |
|
Обратите внимание, что операции REPLACE
и FOR
независимы друг от друга, и u
не определяет автоматически документ для оператора REPLACE
. Таким образом, следующий запрос является некорректным:
1 2 |
|
REPLACE <keyExpression> WITH <document> IN <collection>
¶
При использовании второго синтаксиса документ для замены определяется keyExpression
. Это может быть либо строка с ключом документа, либо объект, содержащий атрибут _key
с ключом документа, либо выражение, которое оценивается как одно из этих двух. Существующий документ с этим ключом заменяется атрибутами, предоставленными объектом document
(за исключением системных атрибутов _id
, _key
и _rev
).
Следующий запрос заменяет документ, идентифицированный ключом my_key
в коллекции users
, устанавливая только атрибуты name
и status
. Ключ передается в виде строки в keyExpression
. Атрибуты для установки передаются отдельно в виде объекта document
:
1 |
|
Объект document
может содержать атрибут _key
, но он игнорируется.
Вы не можете определить документ для замены с помощью атрибута _id
или передать идентификатор документа в виде строки (например, "users/john"
). Однако вы можете использовать PARSE_IDENTIFIER(<id>).key
в качестве keyExpression
, чтобы получить ключ документа в виде строки:
1 2 |
|
Сравнение синтаксисов¶
Оба синтаксиса операции REPLACE
позволяют вам определить документ для изменения и атрибуты для установки. Документ для обновления эффективно идентифицируется ключом документа в сочетании с указанной коллекцией.
Операция REPLACE
поддерживает различные способы указания ключа документа. Вы можете выбрать наиболее удобный для вас вариант синтаксиса.
Следующие запросы эквивалентны:
1 2 |
|
1 2 |
|
1 2 |
|
1 2 |
|
Выражения динамических ключей¶
Операция REPLACE
может заменять произвольные документы, используя любой из двух синтаксисов:
1 2 |
|
1 2 |
|
Нацелить на другую коллекцию¶
Документы, которые изменяет операция REPLACE
, могут находиться в другой коллекции, чем те, которые были созданы предшествующей операцией FOR
:
1 2 3 |
|
Обратите внимание, как документы считываются из коллекции users
, но заменяются в другой коллекции backup
. Для того чтобы это сработало, обе коллекции должны использовать совпадающие ключи документов.
Хотя переменная u
содержит целый документ, она используется только для определения целевого документа. Атрибут _key
объекта извлекается, и целевой документ определяется только значением строки ключа документа и указанной коллекцией операции REPLACE
(backup
). Ссылка на исходную коллекцию (users
) отсутствует.
Параметры запроса¶
Вы можете опционально задать параметры запроса для операции REPLACE
:
1 |
|
ignoreErrors
¶
Вы можете использовать ignoreErrors
для подавления ошибок запроса, которые могут возникнуть при попытке заменить несуществующие документы или при нарушении ограничений уникального ключа:
1 2 3 4 |
|
Вы не можете изменять системные атрибуты _id
, _key
и _rev
, но попытки изменить их игнорируются и не считаются ошибками.
waitForSync
¶
Для обеспечения долговечности данных при возврате запроса замены существует опция запроса waitForSync
:
1 2 3 4 |
|
ignoreRevs
¶
Чтобы случайно не перезаписать документы, которые были изменены с момента последнего извлечения, вы можете использовать опцию ignoreRevs
, чтобы либо позволить ArangoDB сравнивать значение _rev
и добиваться успеха, только если они совпадают, либо позволить ArangoDB игнорировать их (по умолчанию):
1 2 3 4 |
|
exclusive
¶
Движок RocksDB не требует блокировок на уровне коллекции. Различные операции записи в одну и ту же коллекцию не блокируют друг друга, если нет конфликтов запись-запись на одних и тех же документах. С точки зрения разработки приложений может быть желательным иметь исключительный доступ на запись в коллекции, чтобы упростить разработку. Обратите внимание, что записи не блокируют чтения в RocksDB. Исключительный доступ также может ускорить запросы на модификацию, поскольку мы избегаем проверки конфликтов.
Используйте опцию exclusive
для достижения этого эффекта на основе каждого запроса:
1 2 3 4 |
|
refillIndexCaches
¶
Нужно ли обновлять существующие записи в кэше границ в памяти, если документы границ заменяются.
1 2 |
|
Возвращение измененных документов¶
При желании можно вернуть документы, измененные запросом. В этом случае за операцией REPLACE
должна следовать операция RETURN
. Допускаются также промежуточные операции LET
. Эти операции могут ссылаться на псевдопеременные OLD
и NEW
. Псевдопеременная OLD
ссылается на ревизии документа до замены, а NEW
- на ревизии документа после замены.
И OLD
, и NEW
содержат все атрибуты документа, даже те, которые не указаны в выражении replace.
1 2 3 4 |
|
Ниже приведен пример с использованием переменной previous
для возврата исходных документов до их модификации. Для каждого замененного документа возвращается ключ документа:
1 2 3 4 |
|
Следующий запрос использует псевдо-значение NEW
, чтобы вернуть замененные документы без некоторых их системных атрибутов:
1 2 3 4 |
|
Транзакционность¶
На одном сервере операции замены выполняются транзакционно по принципу "все или ничего".
Если используется движок RocksDB и включены промежуточные фиксации, запрос может выполнять промежуточные фиксации транзакций в случае, если запущенная транзакция (AQL-запрос) достигает заданных пороговых значений размера. В этом случае операции запроса, выполненные до этого момента, фиксируются и не откатываются в случае последующего отмены/отката. Это поведение можно контролировать, изменяя настройки промежуточной фиксации для движка RocksDB.
Для коллекций с шардированием вся операция запроса и/или замены может не быть транзакционной, особенно если она затрагивает разные шарды и/или DB-серверы.