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 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":[
        { },
        ...
    ]
}

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.


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