Перейти к содержанию

INSERT

Ключевое слово INSERT может быть использовано для вставки новых документов в коллекцию.

Каждая операция INSERT ограничена одной коллекцией, и имя коллекции не должно быть динамическим. В одном AQL-запросе допускается только один оператор INSERT для одной коллекции, и за ним не могут следовать операции чтения или записи, которые обращаются к той же коллекции, операции обхода или AQL-функции, которые могут читать документы.

Синтаксис

Синтаксис операции вставки следующий:

INSERT document INTO collection

Опционально он может заканчиваться предложением OPTIONS { ... }.

Ключевое слово IN допускается вместо INTO и имеет то же значение.

collection должно содержать имя коллекции, в которую должны быть вставлены документы. document - это документ, который должен быть вставлен, и он может содержать или не содержать атрибут _key. Если атрибут _key не указан, ArangoDB автоматически сгенерирует значение для атрибута _key. При вставке документа также автоматически генерируется номер ревизии документа.

1
2
FOR i IN 1..100
  INSERT { value: i } INTO numbers

Операция вставки также может быть выполнена без цикла FOR для вставки одного документа:

1
INSERT { value: 1 } INTO numbers

При вставке в edge collection обязательно указывать атрибуты _from и _to в документе:

1
2
3
4
FOR u IN users
  FOR p IN products
    FILTER u._key == p.recommendedBy
    INSERT { _from: u._id, _to: p._id } INTO recommendations

Параметры запроса

Ключевое слово OPTIONS, за которым следует объект с параметрами запроса, может быть опционально предоставлено в операции INSERT.

ignoreErrors

ignoreErrors можно использовать для подавления ошибок запроса, которые могут возникнуть при нарушении ограничений уникального ключа:

1
2
3
4
5
6
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { ignoreErrors: true }

waitForSync

Чтобы убедиться, что данные будут долговечными при возврате запроса вставки, существует опция запроса waitForSync:

1
2
3
4
5
6
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { waitForSync: true }

overwrite

Опция overwrite устарела и заменена overwriteMode.

Если вы хотите заменить существующие документы документами с тем же ключом, существует опция запроса overwrite. Это позволит вам безопасно заменить документы вместо того, чтобы выдать ошибку "unique constraint violated error":

1
2
3
4
5
6
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { overwrite: true }

overwriteMode

Для дальнейшего контроля поведения INSERT при нарушении уникальных ограничений первичного индекса существует опция overwriteMode. Она предлагает следующие режимы:

  • "ignore": если документ с указанным значением _key уже существует, ничего не будет сделано и операция записи не будет выполнена. Операция вставки в этом случае возвращает успех. Этот режим не поддерживает возврат старой версии документа. Использование RETURN OLD приведет к ошибке разбора, так как не будет возвращена старая версия. RETURN NEW вернет документ только в том случае, если он был вставлен. Если документ уже существовал, RETURN NEW вернет null.
  • "replace": если документ с указанным значением _key уже существует, он будет перезаписан указанным значением документа. Этот режим также будет использоваться, если режим перезаписи не указан, но флаг overwrite установлен в true.
  • update: если документ с указанным значением _key уже существует, он будет исправлен (частично обновлен) указанным значением документа.
  • "conflict": если документ с указанным значением _key уже существует, вернуть ошибку нарушения уникального ограничения, чтобы операция вставки завершилась неудачно. Это также поведение по умолчанию в случае, если режим перезаписи не установлен, а флаг overwrite равен false или не установлен.

Основное применение вставки документов с режимом перезаписи ignore заключается в том, чтобы убедиться, что определенные документы существуют самым дешевым возможным способом. В случае если целевой документ уже существует, режим ignore является наиболее эффективным, поскольку он не будет извлекать существующий документ из хранилища и не будет записывать в него никаких обновлений.

При использовании режима перезаписи update опции keepNull и mergeObjects управляют тем, как выполняется обновление. См. раздел Операция UPDATE.

1
2
3
4
5
6
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { overwriteMode: "update", keepNull: true, mergeObjects: false }

exclusive.

Движок RocksDB не требует блокировок на уровне коллекции. Различные операции записи в одну и ту же коллекцию не блокируют друг друга, если нет конфликтов запись-запись на одних и тех же документах. С точки зрения разработки приложений может быть желательным иметь исключительный доступ на запись в коллекции, чтобы упростить разработку. Обратите внимание, что записи не блокируют чтения в RocksDB. Исключительный доступ также может ускорить запросы на модификацию, поскольку мы избегаем проверки конфликтов.

Используйте опцию exclusive для достижения этого эффекта на основе каждого запроса:

1
2
3
FOR doc IN collection
  INSERT { myval: doc.val + 1 } INTO users
  OPTIONS { exclusive: true }

refillIndexCaches

Добавлять ли новые записи в кэш границ в памяти при вставке документов границ.

1
2
INSERT { _from: "vert/A", _to: "vert/B" } INTO coll
  OPTIONS { refillIndexCaches: true }

Возврат вставленных документов

Вставленные документы также могут быть возвращены запросом. В этом случае оператор INSERT может быть оператором RETURN (допускаются также промежуточные операторы LET). Для ссылки на вставленные документы оператор INSERT вводит псевдо-значение NEW.

Документы, содержащиеся в NEW, будут содержать все атрибуты, даже те, которые автоматически генерируются базой данных (например, _id, _key, _rev).

1
INSERT document INTO collection RETURN NEW

Ниже приведен пример с использованием переменной inserted для возврата вставленных документов. Для каждого вставленного документа возвращается ключ документа:

1
2
3
4
5
FOR i IN 1..100
  INSERT { value: i }
  INTO users
  LET inserted = NEW
  RETURN inserted._key

Транзакционность

На одном сервере операция вставки выполняется транзакционно по принципу "все или ничего".

Если используется движок RocksDB и включены промежуточные фиксации, запрос может выполнять промежуточные фиксации транзакций в случае, если запущенная транзакция (AQL-запрос) достигнет заданных пороговых значений размера. В этом случае операции запроса, выполненные до сих пор, будут зафиксированы и не будут откатаны в случае последующего прерывания/отката. Это поведение можно контролировать, изменяя настройки промежуточной фиксации для движка RocksDB.

Для коллекций с шардированием вся операция запроса и/или вставки может не быть транзакционной, особенно если в ней участвуют разные шарды и/или DB-серверы.

Комментарии