INSERT ====== The *INSERT* keyword can be used to insert new documents into a collection. On a single server, an insert operation is executed transactionally in an all-or-nothing fashion. If the RocksDB engine is used and intermediate commits are enabled, a query may execute intermediate transaction commits in case the running transaction (AQL query) hits the specified size thresholds. In this case, the query's operations carried out so far will be committed and not rolled back in case of a later abort/rollback. That behavior can be controlled by adjusting the intermediate commit settings for the RocksDB engine. For sharded collections, the entire query and/or insert operation may not be transactional, especially if it involves different shards and/or database servers. Each *INSERT* operation is restricted to a single collection, and the [collection name](../../Manual/Appendix/Glossary.html#collection-name) must not be dynamic. Only a single *INSERT* statement per collection is allowed per AQL query, and it cannot be followed by read or write operations that access the same collection, by traversal operations, or AQL functions that can read documents. The syntax for an insert operation is: ``` INSERT document INTO collection [ OPTIONS options ] ``` **Note**: The *IN* keyword is allowed in place of *INTO* and has the same meaning. *collection* must contain the name of the collection into which the documents should be inserted. *document* is the document to be inserted, and it may or may not contain a *_key* attribute. If no *_key* attribute is provided, ArangoDB will auto-generate a value for *_key* value. Inserting a document will also auto-generate a document revision number for the document. ```js FOR i IN 1..100 INSERT { value: i } INTO numbers ``` An insert operation can also be performed without a *FOR* loop to insert a single document: ```js INSERT { value: 1 } INTO numbers ``` When inserting into an [edge collection](../../Manual/Appendix/Glossary.html#edge-collection), it is mandatory to specify the attributes *_from* and *_to* in document: ```js FOR u IN users FOR p IN products FILTER u._key == p.recommendedBy INSERT { _from: u._id, _to: p._id } INTO recommendations ``` Setting query options --------------------- The *OPTIONS* keyword followed by an object with query options can optionally be provided in an *INSERT* operation. It can be used to suppress query errors that may occur when violating unique key constraints: ```js FOR i IN 1..1000 INSERT { _key: CONCAT('test', i), name: "test", foobar: true } INTO users OPTIONS { ignoreErrors: true } ``` To make sure data are durable when an insert query returns, there is the *waitForSync* query option: ```js FOR i IN 1..1000 INSERT { _key: CONCAT('test', i), name: "test", foobar: true } INTO users OPTIONS { waitForSync: true } ``` If you want to replace existing documents with documents having the same key there is the *overwrite* query option. This will let you safely replace the documents instead of raising an "unique constraint violated error": ```js FOR i IN 1..1000 INSERT { _key: CONCAT('test', i), name: "test", foobar: true } INTO users OPTIONS { overwrite: true } ``` Returning the inserted documents -------------------------------- The inserted documents can also be returned by the query. In this case, the `INSERT` statement can be a `RETURN` statement (intermediate `LET` statements are allowed, too). To refer to the inserted documents, the `INSERT` statement introduces a pseudo-value named `NEW`. The documents contained in `NEW` will contain all attributes, even those auto-generated by the database (e.g. `_id`, `_key`, `_rev`). ```js INSERT document INTO collection RETURN NEW ``` Following is an example using a variable named `inserted` to return the inserted documents. For each inserted document, the document key is returned: ```js FOR i IN 1..100 INSERT { value: i } INTO users LET inserted = NEW RETURN inserted._key ```