Skip to main content

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:

  1. Upload a new document called "person/1".
  2. 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.

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:

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 ParameterTypeDescription
waitForIndexesTimeoutTimeSpanThe amount of time to wait for indexing to complete. Format of TimeSpan.
waitForIndexThrowbooleanSet to true to throw an exception if the indexing doesn't complete before waitForIndexesTimeout.
Set to false to recieve the normal response body.
waitForSpecificIndexstring[]Wait only for the listed indexes to finish updating, rather than all indexes.

Replication Options

Query ParameterTypeDescription
waitForReplicasTimeoutTimeSpanThe amount of time to wait for replication to complete. Format of TimeSpan.
throwOnTimeoutInWaitForReplicasbooleanSet to true to throw an exception if the replication doesn't complete before waitForReplicasTimeout.
Set to false to recieve the normal response body.
numberOfReplicasToWaitForint/stringThe 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\"
}
ParameterDescriptionRequired
IdID of document to create or updateYes to update, no to create
ChangeVectorWhen 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
DocumentJSON document to create, or to replace the existing documentYes
TypeSet to PUTYes
ForceRevisionCreationStrategyWhen 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\"
}
ParameterDescriptionRequired
IdID of a document to execute the patch onYes
ChangeVectorThe document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown.No
PatchA script that modifies the specified document. Details below.Yes
PatchIfMissingAn 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
TypeSet to PATCHYes

Patch Request

Using scripts with arguments allows RavenDB to cache scripts and boost performance. For cURL, use single quotes ' to wrap strings.

Sub-ParameterDescriptionRequired
ScriptJavascript commands to perform on the document. Use arguments from Values with a $ prefix, i.e. $<argument name>.Yes
ValuesArguments 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\"
}
ParameterDescriptionRequired
IdID of document to delete (only one can be deleted per command)Yes
ChangeVectorThe document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown.No
TypeSet to DELETEYes

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\"
}
ParameterDescriptionRequired
IdAll documents whose IDs begin with this string will be deletedYes
IdPrefixedSet to true (distinguishes this as a Delete by Prefix Command rather than the Delete Document Command described above)Yes
TypeSet to DELETEYes

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>--"
ParameterDescriptionRequired
boundaryThe "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
IdDocument IDYes
NameName of attachment to create or updateYes
ContentTypeMime type of the attachmentNo
ChangeVectorThe document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown.No
TypeSet to AttachmentPUTYes

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\"
}
ParameterDescriptionRequired
IdID of document for which to delete the attachmentYes
NameName of the attachment to deleteYes
ChangeVectorThe document's expected change vector. If it does not match the server-side change vector a concurrency exception is thrown.No
TypeSet to AttachmentDELETEYes

Response Format

Http Status Codes

CodeDescription
201The transaction was successfully completed.
408The 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.
409A 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.
500Invalid 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":[
{ },
...
]
}

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

StatusDescription
DocumentDoesNotExistNo document with the specified ID exists. This will only be returned if no PatchIfMissing script was given.
CreatedNo document with the specified ID existed, so a new document was created with that ID and PatchIfMissing was applied.
PatchedThe specified document was successfully patched.
SkippedShould not appear in the context of batch commands.
NotModifiedPatch 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.

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"
}
]
}