Batch Commands
-
Use this endpoint with the
POST
method to send multiple commands in one request:
<server URL>/databases/<database name>/bulk_docs
-
The commands are sent as a JSON array in the request body.
-
All the commands in the batch will either succeed or fail as a single transaction. Changes will not be visible until the entire batch completes.
-
Options can be set to make the server wait for indexing and replication to complete before returning.
-
In this page:
Basic Example
This is a cURL request to a database named "Example" on our playground server.
It batches two commands:
- Upload a new document called "person/1".
- Execute a patch on that same document.
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{
\"Id\": \"person/1\",
\"ChangeVector\": null,
\"Document\": {
\"Name\": \"John Smith\"
},
\"Type\": \"PUT\"
},
{
\"Id\": \"person/1\",
\"ChangeVector\": null,
\"Patch\": {
\"Script\": \"this.Name = 'Jane Doe';\",
\"Values\": {}
},
\"Type\": \"PATCH\"
}
]
}"
Linebreaks are added for clarity.Response:
HTTP/1.1 201 Created
Server: nginx
Date: Sun, 15 Sep 2019 14:12:30 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
Vary: Accept-Encoding
Raven-Server-Version: 4.2.4.42
{
"Results": [
{
"Type": "PUT",
"@id": "person/1",
"@collection": "@empty",
"@change-vector": "A:1-urx5nDNUT06FCpCon1wCyA",
"@last-modified": "2019-09-15T14:12:30.0425811"
},
{
"Id": "person/1",
"ChangeVector": "A:2-urx5nDNUT06FCpCon1wCyA",
"LastModified": "2019-09-15T14:12:30.0495095",
"Type": "PATCH",
"PatchStatus": "Patched",
"Debug": null
}
]
}
Request Format
This is the general format of a cURL request with a batch of commands that does not include a Put Attachment Command (see the format for batching a Put Attachment Command below):
curl -X POST "<server URL>/databases/<database name>/bulk_docs?<batch options>"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{ <command> },
...
]
}"
Linebreaks are added for clarity.Query String
The query string takes batch options, which
can make the server wait for indexing and replication to finish before responding.
Header
The header Content-Type
is required and takes one of two values:
application/json
- if the batch does not include a Put Attachment Command.multipart/mixed; boundary=<separator>
- if the batch does include a Put Attachment Command. The "separator" is an arbitrary string used to demarcate the attachment streams and commands array.
Body
The body contains a JSON array of commands.
-d "{
\"Commands\": [
{
\"Id\": \"<document ID>\",
...
\"Type\": \"<command type>\"
},
{ <command> },
...
]
}"
Depending on the shell you're using to run cURL, you will probably need to escape all double quotes within the request body
using a backslash: "
-> \"
.
The following commands can be sent using the batch command:
- Put Document Command
- Patch Document Command
- Delete Document Command
- Delete by Prefix Command
- Put Attachment Command
- Delete Attachment Command
Batch Options
These options, configured in the query string, make the server wait until indexing or replication have completed before responding. If these have not completed before a specified amount of time has passed, the server can either respond as normal or throw an exception.
This is the general format of a cURL request that includes batch options in the query string:
curl -X POST "<server_URL>/databases/<database_name>/bulk_docs?<batch option>=<value>
&<batch option>=<value>
&<batch option>=<value>
..."
-H "Content-Type: <content_type>"
-d "{ }"
Linebreaks are added for clarity.Indexing Options
Query Parameter | Type | Description |
---|---|---|
waitForIndexesTimeout | TimeSpan |
The amount of time to wait for indexing to complete. Format of TimeSpan . |
waitForIndexThrow | boolean |
Set to true to throw an exception if the indexing doesn't complete before waitForIndexesTimeout .Set to false to recieve the normal response body. |
waitForSpecificIndex | string[] |
Wait only for the listed indexes to finish updating, rather than all indexes. |
Replication Options
Query Parameter | Type | Description |
---|---|---|
waitForReplicasTimeout | TimeSpan |
The amount of time to wait for replication to complete. Format of TimeSpan . |
throwOnTimeoutInWaitForReplicas | boolean |
Set to true to throw an exception if the replication doesn't complete before waitForReplicasTimeout .Set to false to recieve the normal response body. |
numberOfReplicasToWaitFor | int /string |
The number of replicas that should be made before waitForReplicasTimeout . Set this parameter to majority to wait until the data has been replicated to a majority of the nodes in the database group. Default = 1 . |
Commands
Put Document Command
Upload a new document or update an existing document.
Format within the Commands
array in the request body:
{
\"Id\": \"<document ID>\",
\"ChangeVector\": \"<expected change vector>\",
\"Document\": {
<document content>
},
\"Type\": \"PUT\",
\"ForceRevisionCreationStrategy\": \"Before\"
}
Parameter | Description | Required |
---|---|---|
Id | ID of document to create or update | Yes to update, no to create |
ChangeVector | When updating an existing document, this parameter that document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown. An exception is also thrown if the document does not exist. |
No |
Document | JSON document to create, or to replace the existing document | Yes |
Type | Set to PUT |
Yes |
ForceRevisionCreationStrategy | When updating an existing document, set to Before to make a revision of the document before it is updated. |
No |
Patch Document Command
Update a document. A patch is executed on the server side and does not involve loading the document, avoiding the cost of sending the entire document in a round trip over the network.
Format within the Commands
array in the request body:
{
\"Id\": \"<document ID>\",
\"ChangeVector\": \"<expected change vector>\",
\"Patch\": {
\"Script\": \"<javascript code using $<argument name> >\",
\"Values\": {
\"<argument name>\": \"<value>\",
...
}
},
\"PatchIfMissing\": {
\"Script\": \"<javascript code>\",
\"Values\": {
<arguments>
}
},
\"Type\": \"PATCH\"
}
Parameter | Description | Required |
---|---|---|
Id | ID of a document to execute the patch on | Yes |
ChangeVector | The document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown. | No |
Patch | A script that modifies the specified document. Details below. | Yes |
PatchIfMissing | An alternative script to be executed if no document with the given ID is found. This will create a new document with the given ID. Details below. | No |
Type | Set to PATCH |
Yes |
Patch Request
Using scripts with arguments allows RavenDB to cache scripts and boost performance. For cURL, use single quotes '
to
wrap strings.
Sub-Parameter | Description | Required |
---|---|---|
Script | Javascript commands to perform on the document. Use arguments from Values with a $ prefix, i.e. $<argument name> . |
Yes |
Values | Arguments that can be used in the script. | No |
Delete Document Command
Delete a document by its ID.
Format within the Commands
array in the request body:
{
\"Id\": \"<document ID>\",
\"ChangeVector\": \"<expected change vector>\",
\"Type\": \"DELETE\"
}
Parameter | Description | Required |
---|---|---|
Id | ID of document to delete (only one can be deleted per command) | Yes |
ChangeVector | The document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown. | No |
Type | Set to DELETE |
Yes |
Delete by Prefix Command
Delete all documents whose IDs begin with a certain prefix.
Format within the Commands
array in the request body:
{
\"Id\": \"<document ID prefix>\",
\"IdPrefixed\": true,
\"Type\": \"DELETE\"
}
Parameter | Description | Required |
---|---|---|
Id | All documents whose IDs begin with this string will be deleted | Yes |
IdPrefixed | Set to true (distinguishes this as a Delete by Prefix Command rather than the Delete Document Command described above) |
Yes |
Type | Set to DELETE |
Yes |
Put Attachment Command
Add an attachment to a document, or update an existing attachment.
If a batch contains a Put Attachment Command, the cURL format of the request is slightly different from a batch that doesn't.
The Content-Type
header takes multipart/mixed; boundary="<separator>"
instead of the default application/json
.
The body contains the Commands
array followed by each of the attachments, passed in the form of binary streams. The attachment streams come in the
same order as their respective Put Attachment Commands within the Commands
array. The separator
demarcates these sections.
The general form of a cURL request:
curl -X POST "<server URL>/databases/<database name>/bulk_docs"
-H "Content-Type: multipart/mixed; boundary=<separator>"
-d "
--<separator>
{
\"Commands\":[
{
\"Id\": \"<document ID>\",
\"Name\": \"<attachment name>\",
\"ContentType\": \"<attachment MIME type>\"
\"ChangeVector\": \"<expected change vector>\",
\"Type\": \"AttachmentPUT\"
},
...
]
}
--<separator>
Command-Type: AttachmentStream
<binary stream>
--<separator>
...
--<separator>--"
Parameter | Description | Required |
---|---|---|
boundary | The "separator" - an arbitrary string that demarcates the attachment streams. The attachment streams come in the same order as their respective Put Attachment Commands in the commands array. The string used as a separator must not appear elsewhere in the request body - i.e. "ChangeVector" or "[{" are not valid separators. |
Yes |
Id | Document ID | Yes |
Name | Name of attachment to create or update | Yes |
ContentType | Mime type of the attachment | No |
ChangeVector | The document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown. | No |
Type | Set to AttachmentPUT |
Yes |
Delete Attachment Command
Delete an attachment in a certain document.
Format within the Commands
array in the request body:
{
\"Id\": \"<document ID>\",
\"Name\": \"<attachment name>\",
\"ChangeVector\": \"<expected change vector>\",
\"Type\": \"AttachmentDELETE\"
}
Parameter | Description | Required |
---|---|---|
Id | ID of document for which to delete the attachment | Yes |
Name | Name of the attachment to delete | Yes |
ChangeVector | The document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown. | No |
Type | Set to AttachmentDELETE |
Yes |
Response Format
Http Status Codes
Code | Description |
---|---|
201 |
The transaction was successfully completed. |
408 |
The time specified by the options waitForIndexThrow or waitForReplicasTimeout passed before indexing or replication completed respectively, and an exception is thrown. This only happens if throwOnTimeoutInWaitForReplicas or waitForIndexThrow are set to true . |
409 |
A specified change vector did not match the server-side change vector, or a change vector was specified for a document that does not exist. A concurrency exception is thrown. |
500 |
Invalid request, such as a put attachment command for a document that does not exist. |
Response Body
Results appear in the same order as the commands in the request body.
{
"Results":[
{ },
...
]
}
-
Format within the
Results
array in the response body:
Put Document Command
{
"Type": "PUT",
"@id": "<document ID>",
"@collection": "<collection name>",
"@change-vector": "<current change vector>",
"@last-modified": "<date and time UTC>"
}
Parameter | Description | |
---|---|---|
Type | Same as the Type of the command sent - in this case PUT . |
|
@id | The ID of the document that has been created or modified. | |
@collection | Name of the collection that contains the document. If none was specified, the collection will be @empty . |
|
@change-vector | The document's change vector after the command was executed. |
Patch Document Command
{
"@id": "<document ID>",
"@change-vector": "<current change vector>",
"@last-modified": "<date and time UTC>",
"Type": "PATCH",
"PatchStatus": "<patch status>",
"Debug": null
}
Parameter | Description | |
---|---|---|
@id | The ID of the document that has been patched or created. | |
@change-vector | The document's change vector after the command was executed. Returns null if the command did not result in any changes. |
|
@last-modified | Date and time (UTC) of the most recent modification made to the document. | |
Type | Same as the Type of the command sent - in this case PATCH . |
|
PatchStatus | See below | |
Debug | Should always return null in the context of batch commands. |
PatchStatus
Status | Description |
---|---|
DocumentDoesNotExist | No document with the specified ID exists. This will only be returned if no PatchIfMissing script was given. |
Created | No document with the specified ID existed, so a new document was created with that ID and PatchIfMissing was applied. |
Patched | The specified document was successfully patched. |
Skipped | Should not appear in the context of batch commands. |
NotModified | Patch was successful but did not result in a modification to the document. |
Delete Document Command
{
"Id": "<document ID>",
"Type": "DELETE",
"Deleted": <boolean>
}
Parameter | Description | |
---|---|---|
Id | The ID of the document that has been deleted. | |
Type | Same as the Type of the command sent - in this case DELETE . |
|
Deleted | true if the document was successfully deleted, false if not (for instance, because the specified document did not exist). |
Delete by Prefix Command
{
"Id": "<prefix>",
"Type": "DELETE",
"Deleted": <boolean>
}
Parameter | Description | |
---|---|---|
Id | The document ID prefix of the documents that were deleted. | |
Type | Same as the Type of the command sent - in this case DELETE . |
|
Deleted | true if the documents were successfully deleted, false if not (for instance, because no documents with the specified prefix exist). |
Put Attachment Command
{
"Id": "<document ID>",
"Type": "AttachmentPUT",
"Name": "<attachment name>",
"ChangeVector": "<attachment change vector>",
"Hash": "<Hash>",
"ContentType": "<MIME type>",
"Size": <attachment size in bytes>,
"DocumentChangeVector": "<current change vector>"
}
Parameter | Description | |
---|---|---|
Id | The ID of the document for which the attachment was put. | |
Type | Same as the Type of the command sent - in this case AttachmentPUT . |
|
Name | Name of the attachment that was created or updated. | |
ChangeVector | A change vector specific to the attachment, distinct from the usual document change vector. Use this change vector in requests to update this attachment. | |
Hash | Hash representing the attachment. | |
ContentType | MIME type of the attachment. | |
Size | Size of the attachment in bytes. | |
DocumentChangeVector | The document's change vector after the command was executed. |
Delete Attachment Command
{
"Type": "AttachmentDELETE",
"@id": "<document ID>",
"Name": "<attachment name",
"DocumentChangeVector": "<current change vector>"
}
Parameter | Description | |
---|---|---|
Type | Same as the Type of the command sent - in this case AttachmentDELETE . |
|
@id | The ID of the document for which the attachment was deleted. | |
Name | Name of the attachment that was deleted. | |
DocumentChangeVector | The document's change vector after the command was executed. |
More Examples
About Northwind, the database used in our examples.
- In this section:
Put Document Command
Request:
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{
\"Id\": \"person/1\",
\"ChangeVector\": null,
\"Document\": {
\"Name\": \"John Smith\"
},
\"Type\": \"PUT\"
}
]
}"
Response:
HTTP/1.1 201 Created
Server:"nginx"
Date:"Wed, 18 Sep 2019 16:14:20 GMT"
Content-Type:"application/json; charset=utf-8"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
Raven-Server-Version:"4.2.4.42"
{
"Results": [
{
"Type": "PUT",
"@id": "person/1",
"@collection": "@empty",
"@change-vector": "A:5951-pITDlhlRaEeJh16dDBREzg, A:1887-0N64iiIdYUKcO+yq1V0cPA, A:6214-xwmnvG1KBkSNXfl7/0yJ1A",
"@last-modified": "2019-09-18T16:14:20.5759532"
}
]
}
Patch Document Command
Request:
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{
\"Id\": \"person/1\",
\"ChangeVector\": null,
\"Patch\": {
\"Script\": \"this.Name = 'Jane Doe';\",
\"Values\": {}
},
\"Type\": \"PATCH\"
}
]
}"
Response:
HTTP/1.1 201 Created
Server:"nginx"
Date:"Wed, 18 Sep 2019 16:18:13 GMT"
Content-Type:"application/json; charset=utf-8"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
Raven-Server-Version:"4.2.4.42"
{
"Results": [
{
"Id": "person/1",
"ChangeVector": "A:5952-pITDlhlRaEeJh16dDBREzg, A:1887-0N64iiIdYUKcO+yq1V0cPA, A:6214-xwmnvG1KBkSNXfl7/0yJ1A",
"LastModified": "2019-09-18T16:18:13.5745560",
"Type": "PATCH",
"PatchStatus": "Patched",
"Debug": null
}
]
}
Delete Document Command
Request:
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{
\"Id\": \"employees/1-A\",
\"ChangeVector\": null,
\"Type\": \"DELETE\"
}
]
}"
Response:
HTTP/1.1 201 Created
Server:"nginx"
Date:"Wed, 18 Sep 2019 16:30:15 GMT"
Content-Type:"application/json; charset=utf-8"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
Raven-Server-Version:"4.2.4.42"
{
"Results": [
{
"Id": "employees/1-A",
"Type": "DELETE",
"Deleted": true,
"ChangeVector": null
}
]
}
Delete by Prefix Command
Request:
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{
\"Id\": \"employ\",
\"ChangeVector\": null,
\"IdPrefixed\": true,
\"Type\": \"DELETE\"
}
]
}"
Response:
HTTP/1.1 201 Created
Server:"nginx"
Date:"Wed, 18 Sep 2019 16:32:16 GMT"
Content-Type:"application/json; charset=utf-8"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
Raven-Server-Version:"4.2.4.42"
{
"Results": [
{
"Id": "employ",
"Type": "DELETE",
"Deleted": true
}
]
}
Put Attachment Command
Request:
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: multipart/mixed; boundary=some_boundary"
-d "
--some_boundary
{
\"Commands\": [
{
\"Id\":\"shippers/1-A\",
\"Name\":\"some_file\",
\"ContentType\":\"text\"
\"Type\":\"AttachmentPUT\",
}
]
}
--some_boundary
Command-Type: AttachmentStream
12345
--some_boundary--"
Response:
HTTP/1.1 201 Created
Server:"nginx"
Date:"Wed, 18 Sep 2019 16:40:43 GMT"
Content-Type:"application/json; charset=utf-8"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
Raven-Server-Version:"4.2.4.42"
{
"Results": [
{
"Id": "shippers/1-A",
"Type": "AttachmentPUT",
"Name": "some_file",
"ChangeVector": "A:5973-pITDlhlRaEeJh16dDBREzg, A:1887-0N64iiIdYUKcO+yq1V0cPA, A:6214-xwmnvG1KBkSNXfl7/0yJ1A",
"Hash": "DHnN2gtPymAUoaFxtgjxfU83O8fxGHw8+H/P+kkPxjg=",
"ContentType": "text",
"Size": 5,
"DocumentChangeVector": "A:5974-pITDlhlRaEeJh16dDBREzg, A:1887-0N64iiIdYUKcO+yq1V0cPA, A:6214-xwmnvG1KBkSNXfl7/0yJ1A"
}
]
}
Delete Attachment Command
Request:
curl -X POST "http://live-test.ravendb.net/databases/Example/bulk_docs"
-H "Content-Type: application/json"
-d "{
\"Commands\": [
{
\"Id\": \"categories/2-A\",
\"Name\": \"image.jpg\",
\"ChangeVector\": null,
\"Type\": \"AttachmentDELETE\"
}
]
}"
Response:
HTTP/1.1 201 Created
Server:"nginx"
Date:"Wed, 18 Sep 2019 16:44:40 GMT"
Content-Type:"application/json; charset=utf-8"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
Raven-Server-Version:"4.2.4.42"
{
"Results": [
{
"Type": "AttachmentDELETE",
"@id": "categories/2-A",
"Name": "image.jpg",
"DocumentChangeVector": "A:5979-pITDlhlRaEeJh16dDBREzg, A:1887-0N64iiIdYUKcO+yq1V0cPA, A:6214-xwmnvG1KBkSNXfl7/0yJ1A"
}
]
}