Patch a Single Document: API Overview
-
Use the Patch operation to update selected parts of a document without requiring the client to load, modify,
and save the full document. -
The patch is sent in a single request and applied atomically by the server in a single write transaction.
This reduces client-server traffic and is especially useful when updating denormalized data. -
This article covers patching a single document through the Client API.
To patch multiple documents that match specified criteria, see
Patch Multiple Documents - Using the Client API or
Patch Multiple Documents - Using Studio. -
In this article:
API overview
-
You can patch a single document through any of the following Client API approaches:
- Session API
Use session helper methods for common patch operations. - Session API using Defer
Queue a custom JavaScript patch command as part of the session. - Operations API
Send a custom JavaScript patch command directly through the document store, without using a session.
- Session API
-
Each section below includes a basic example.
For additional examples using all three APIs, see: -
Refer to the Syntax section for detailed method signatures.
Session API
The type-safe Session.Advanced API provides the following methods for common single-document patch operations:
PatchAddOrPatchIncrementAddOrIncrement
Example: Modify a single field
- Sync
- Async
// Modify FirstName to Robert
// With the default convention, this typed call generates a JSON Patch command.
session.Advanced.Patch<Employee, string>(
"employees/1",
x => x.FirstName, "Robert");
session.SaveChanges();
// Modify FirstName to Robert
// With the default convention, this typed call generates a JSON Patch command.
asyncSession.Advanced.Patch<Employee, string>(
"employees/1",
x => x.FirstName, "Robert");
await asyncSession.SaveChangesAsync();
Custom patch scripts:
To run a custom patch script containing computations, conditions, loops, or calls to RavenDB's patching functions,
use Defer or the Operations API.
Saving session patches:
Calls to these methods are queued in the session
and sent to the server only when SaveChanges is called.
SaveChanges() sends the patch commands together with all other changes tracked by the session -
including stored, modified, and deleted documents - as a single batch in one HTTP request.
Missing documents:
If the target document does not exist, session-generated Patch and Increment commands make no changes,
and SaveChanges() does not throw.
Use AddOrPatch or AddOrIncrement when a missing document should be created.
This differs from an explicitly sent JsonPatchOperation, which throws if the target document does not exist.
Transaction guarantees:
The server executes the entire SaveChanges batch in one ACID transaction.
If the server cannot execute any command in the batch, for example because of a patch error or a concurrency conflict, SaveChanges() throws; awaiting SaveChangesAsync() also throws.
The server rolls back the transaction, and none of the changes in the batch are persisted.
When the save call completes successfully, the entire batch has been persisted.
Optimistic concurrency:
Patch commands generated by these typed Session API methods carry no change vector in either command format,
even when optimistic concurrency is enabled.
Consequently, these generated patch commands are not rejected merely because the target document changed after the patch was queued.
Another command in the batch - such as a stored document or an explicitly deferred
PatchCommandData that supplies a change vector - can still fail with a concurrency conflict.
Patching a modified document tracked by the same session:
If the session tracks the target document and considers it modified, SaveChanges() throws an InvalidOperationException; awaiting SaveChangesAsync() also throws.
This restriction applies whether you pass the document ID or the tracked entity to a typed Session API patch method,
and regardless of which command format the client selects (see JSON Patch and JavaScript patch formats).
It also applies to a PatchCommandData queued with Defer.
The exception message identifies the patch command format selected by the client:
Cannot perform save because document <id> has been modified by the session and is also taking part in deferred <command-type> command,
where <command-type> is JsonPatch for JSON Patch or PATCH for JavaScript patching.
For a document loaded into the session, the client detects entity changes by serializing the entity and comparing the resulting document with the snapshot taken when the document was loaded.
Consequently, the entity can be considered modified even when you did not edit it.
For example:
- A property represented by the .NET model but absent from the stored document can be serialized with its CLR default value and reported as a new field.
- By default, the client preserves stored properties that are not represented by the .NET model.
If PreserveDocumentPropertiesNotFoundOnModel is set tofalse, those properties are omitted when the entity is serialized and reported as removed.
Changes made through the session's metadata API can also cause the document to be considered modified.
To persist only the patch, either queue it in a separate session that is not tracking the target document,
or call session.Advanced.IgnoreChangesFor(entity) at any point before the save call.
IgnoreChangesFor does not revert or remove the entity's in-memory edits.
It prevents the session from sending a document update for those edits; the queued patch is still sent.
While the entity remains tracked, subsequent save calls will continue to ignore its changes.
Use this method only when the patch is the only change you want persisted for that document.
JSON Patch and JavaScript patch formats
For the .NET typed Session.Advanced.Patch overloads, the client queues the requested change internally as either an RFC 6902 JSON Patch command or a JavaScript patch command.
You continue using the same session patch methods regardless of which patch format is selected.
How the patch formats differ
| Patch format | How the change is represented |
|---|---|
| JSON Patch | A standardized, declarative list of operations. Each operation contains an op and a path into the document, and may also contain a value or from path. The server applies these operations directly without executing a JavaScript patch script. |
| JavaScript patch | A JavaScript script with optional parameter values. The script can contain computations, conditions, loops, and calls to RavenDB's patching functions. |
JSON Patch has a fixed set of operations: add, remove, replace, move, copy, and test.
JavaScript remains available for changes that cannot be expressed using this fixed set.
JSON Patch: selection and generated operations
Default behavior:
By default, the client uses the SessionPatchBehavior convention with the value SessionPatchBehavior.JsonPatch.
With this default, the client generates JSON Patch commands when the requested operation, value, and path can be represented as JSON Patch for:
- Setting a property.
- Adding one or more items to an array.
- Removing an array item with
RemoveAt. - Adding or removing a dictionary entry.
Generated operations:
When setting a named property, the generated JSON Patch uses add, which creates the property if it does not exist or replaces its value if it does.
An array path ending in /- appends an item to the array.
When assigning a value to an existing array or list position, such as x => x.Items[0], the client generates a replace operation.
This overwrites the item at that position without inserting a new item or shifting the remaining items.
JavaScript: fallback and explicit selection
Fallback conditions:
If a requested operation, value, or path cannot be represented as JSON Patch,
the client automatically falls back to a JavaScript patch command. For example:
-
RemoveAllwith a predicate falls back to JavaScript. -
Increment,AddOrIncrement, andAddOrPatchalways use JavaScript patch commands and are not controlled by this convention. -
Non-null reference-type values other than
string, such as nested objects or polymorphic values,
require a JavaScript fallback.
DateOnlyandTimeOnlyvalues also require a JavaScript fallback.
Other value-type values do not by themselves cause a fallback. This includes custom structs, which are serialized using the store's serialization conventions. -
Paths the client cannot convert to a JSON Pointer, such as paths containing a non-constant array or list index, also require a JavaScript fallback. A path that indexes into a dictionary with a non-numeric key, such as
x => x.Preferences["language"], always requires a JavaScript fallback,
because the client builds JSON Pointer segments from property names and constant numeric indexes only.
Empty or whitespace dictionary keys also fall back because RavenDB rejects them as JSON Pointer path segments.
Pending JavaScript patches:
A JavaScript patch command that is already queued for the same document also forces a fallback:
while such a command is pending, subsequent Patch calls that would otherwise generate JSON Patch are generated as JavaScript and merged into the pending command.
The order of the calls therefore affects the queued commands:
Incrementfollowed byPatchproduces a single merged JavaScript patch command.- A JSON-Patch-eligible
Patchfollowed byIncrementproduces two commands -
a JSON Patch command followed by a JavaScript patch command.
In both cases, RavenDB preserves the call order and executes the resulting command or commands in the same transaction.
Reversing the calls can still change the final value when both operations modify the same field.
When a fallback occurs, any behavior that differs between the command formats follows the JavaScript semantics described below.
Selecting JavaScript explicitly:
To make all typed Session.Advanced.Patch calls use JavaScript patch commands,
set the convention to SessionPatchBehavior.JavaScript.
This automatic command selection applies only to the .NET typed Session.Advanced.Patch overloads.
JavaScript patches created explicitly with PatchCommandData or PatchOperation remain JavaScript commands.
This includes PatchCommandData registered through Session.Advanced.Defer.
Differences in behavior
Missing or out-of-range targets:
The command formats differ when a removal target or indexed array element does not exist:
-
With
SessionPatchBehavior.JsonPatch,SaveChanges()throws aRavenExceptionwhen:RemoveAttargets an out-of-range array index.- Dictionary
Removetargets a key that does not exist. - An indexed assignment targets an out-of-range position,
because the generatedreplaceoperation requires the element to exist.
Because the batch is atomic, none of its changes are persisted.
-
With
SessionPatchBehavior.JavaScript, aRemoveAtwith a non-negative index at or beyond the array length, or a missing dictionary key, is treated as a no-op.
Assigning beyond the current array length is handled as a JavaScript array assignment rather than an RFC 6902replace. No exception is thrown, and other valid changes in the batch can still be applied.
Negative array indexes:
A negative index is not out of range, and the two settings treat it differently:
-
With
SessionPatchBehavior.JsonPatch,RemoveAt(-N)generates aremoveoperation whose JSON Pointer path ends in-N. The server rejects a negative array position as out of bounds, soSaveChanges()throws and the batch is rolled back. The index is not counted from the end. -
With
SessionPatchBehavior.JavaScript,RemoveAtgeneratessplice(index, 1),
and JavaScriptsplicetreats a negative index as an offset from the end of the array.
RemoveAt(-N)removes the Nth item from the end andRemoveAt(-1)removes the last item.
Exactly one item is removed in either case.
Sending JSON Patch explicitly
To construct and send RFC 6902 operations explicitly, use JsonPatchOperation.
This is separate from the automatic JSON Patch generation performed by the typed session API.
Learn more in Patch a single document using JSON Patch.
Session API using Defer
-
Use
Session.Advanced.Deferto queue a low-level patch command instead of using the type-safe
Session.Advanced.Patchmethods. Defining the command yourself gives you full control over the
patch script and access to options the typed methods do not expose. -
Create a
PatchRequestcontaining a JavaScript script and optional parameter values,
then pass it in aPatchCommandDatafor the document you want to patch.
PatchCommandDataalso accepts an optionalchangeVector, which enforces optimistic concurrency
for the patch, and an optionalpatchIfMissingscript, which runs when the document does not exist.
TheSession.Advanced.Patchoverloads expose neither option.PatchCommandDataalso has aCreateIfMissingproperty,
which supplies a full document to store when the target document does not exist, instead of a script to run. -
Deferadds thePatchCommandDatato the session's unit of work.
The command is sent to the server only whenSaveChanges()is called,
together with the session's other pending changes in a single request and transaction.
Example: Modify a single field
- Sync
- Async
// Modify FirstName to Robert
// Define and defer a JavaScript patch command.
session.Advanced.Defer(new PatchCommandData(
id: "employees/1",
changeVector: null,
patch: new PatchRequest
{
Script = @"this.FirstName = args.FirstName;",
Values =
{
{"FirstName", "Robert"}
}
},
patchIfMissing: null));
session.SaveChanges();
// Modify FirstName to Robert
// Define and defer a JavaScript patch command.
asyncSession.Advanced.Defer(new PatchCommandData(
id: "employees/1",
changeVector: null,
patch: new PatchRequest
{
Script = @"this.FirstName = args.FirstName;",
Values =
{
{"FirstName", "Robert"}
}
},
patchIfMissing: null));
await asyncSession.SaveChangesAsync();
Patch failures:
If the server cannot compile or execute the deferred JavaScript patch script, SaveChanges() throws;
awaiting SaveChangesAsync() also throws.
The server rolls back the entire session batch, so neither partial changes from the patch nor any other changes in the batch are persisted.
Deferred and immediate execution:
PatchCommandData implements ICommandData, which represents command data included in a batch;
it is not a RavenCommand that can be executed directly through a request executor.
To send a single-document patch without waiting for SaveChanges(), use the Operations API described below.
Mixing deferred and typed patches:
Avoid calling a typed Patch after deferring a PatchCommandData for the same document in the same session.
The typed call is generated as JavaScript and merged into the deferred command, but the merge does not preserve
the deferred command's changeVector or patchIfMissing script. To keep the changes in one transaction, express
them all in the deferred script; otherwise, send them in separate SaveChanges() calls or sessions.
Conflicts with tracked document changes:
A deferred PatchCommandData is subject to the same session-tracking restriction described in the Session API,
(see Patching a modified document tracked by the same session).
If the session also considers the target document modified, SaveChanges() throws, and awaiting SaveChangesAsync() also throws, instead of sending both changes.
Operations API
-
Creating and executing the operation:
Use the Operations API to patch a single document directly through the document store,
without opening a session.Create a
PatchRequestcontaining a JavaScript script and optional parameter values, then pass it toPatchOperationtogether with the document ID and any optional concurrency or missing-document settings.Execute the operation with
store.Operations.Send()orSendAsync(). Unlike a deferred session command,
the patch is sent to the server immediately in its own HTTP request and its own transaction,
and does not wait forSaveChanges(). Separate operations are therefore not applied atomically together.
Example: Modify a single field
- Sync
- Async
// Modify FirstName to Robert
// Send a JavaScript patch directly through the Operations API.
store.Operations.Send(new PatchOperation(
id: "employees/1",
changeVector: null,
patch: new PatchRequest
{
Script = @"this.FirstName = args.FirstName;",
Values =
{
{"FirstName", "Robert"}
}
},
patchIfMissing: null));
// Modify FirstName to Robert
// Send a JavaScript patch directly through the Operations API.
await store.Operations.SendAsync(new PatchOperation(
id: "employees/1",
changeVector: null,
patch: new PatchRequest
{
Script = @"this.FirstName = args.FirstName;",
Values =
{
{"FirstName", "Robert"}
}
},
patchIfMissing: null));
-
Patch failures:
If the server cannot compile or execute the JavaScript patch script,Send()throws;
awaitingSendAsync()also throws. NoPatchStatusis returned.
The server rolls back the operation's transaction, and no partial changes from the operation are persisted. -
Patch status:
Sendreturns aPatchStatus. If no document with the given ID is found and nopatchIfMissingscript
was provided, the returned status isPatchStatus.DocumentDoesNotExistand no exception is thrown.
This differs from an explicitly sent JsonPatchOperation, which throws when the target document does not exist.If
skipPatchIfChangeVectorMismatchistrue, a change-vector mismatch skips the patch and is reported
asPatchStatus.NotModified. With the defaultfalse, a mismatch throws aConcurrencyExceptioninstead. -
Returning the document:
To obtain the document returned by the server, use the genericPatchOperation<TEntity>type.
store.Operations.Send<TEntity>()returns aPatchOperation.Result<TEntity>containing the patchStatusandDocument.Documentcontains the resulting document when the status isCreatedorPatched.
It is also populated when the patch executes but makes no changes and returnsPatchStatus.NotModified.
It isnullwhen the target document does not exist and nopatchIfMissingscript was supplied,
or when the server skips the patch.See Operations API syntax for the method signatures and the
Result<TEntity>properties.
Syntax
Session API syntax
The type-safe Session.Advanced interface exposes the following patch methods.
The typed Session API does not accept a field path as a string.
Instead, the path argument is a lambda expression, such as x => x.FirstName.
The client converts the members in this expression to their stored JSON property names according to the document conventions, whether the operation is generated as JSON Patch or as a JavaScript patch command.
Session.Advanced.Patch
void Patch<T, U>(string id, Expression<Func<T, U>> path, U value);
void Patch<T, U>(T entity, Expression<Func<T, U>> path, U value);
| Parameters | Type | Description |
|---|---|---|
| T | Type | Entity type |
| U | Type | Field type |
| entity | T | Entity on which the operation should be performed. The entity should be one that was returned by the current session in a Load or Query operation. This way the session can track down the entity's ID. |
| id | string | Entity ID on which the operation should be performed. |
| path | Expression<Func<T, U>> | Lambda describing the path to the field. |
| value | U | Value to set. |
path may also index into a dictionary, for example x => x.Preferences["language"],
to set a single entry without replacing the rest of the dictionary.
The key can be a literal, a local variable, or a property of another object.
Assigning to a key that does not exist creates it.
A dictionary-indexed path is always sent as a JavaScript patch command,
see JSON Patch and JavaScript patch formats.
Session.Advanced.AddOrPatch
void AddOrPatch<T, TU>(string id, T entity, Expression<Func<T, TU>> path, TU value);
| Parameters | Type | Description |
|---|---|---|
| T | Type | Entity type |
| TU | Type | Field type |
| entity | T | Entity on which the operation should be performed. The entity should be one that was returned by the current session in a Load or Query operation. This way the session can track down the entity's ID. |
| id | string | Entity ID on which the operation should be performed. |
| path | Expression<Func<T, TU>> | Lambda describing the path to the field. |
| value | TU | Value to set. |
Session.Advanced.Increment
void Increment<T, U>(T entity, Expression<Func<T, U>> path, U valToAdd);
void Increment<T, U>(string id, Expression<Func<T, U>> path, U valToAdd);
| Parameters | Type | Description |
|---|---|---|
| T | Type | Entity type |
| U | Type | Field type, must be a numeric type, or a string or char for string concatenation |
| entity | T | Entity on which the operation should be performed. The entity should be one that was returned by the current session in a Load or Query operation, this way, the session can track down the entity's ID |
| id | string | Entity ID on which the operation should be performed. |
| path | Expression<Func<T, U>> | Lambda describing the path to the field. |
| valToAdd | U | Value to be added. |
- Note how numbers are handled with the JavaScript engine in RavenDB.
Session.Advanced.AddOrIncrement
void AddOrIncrement<T, TU>(string id, T entity, Expression<Func<T, TU>> path, TU valToAdd);
| Parameters | Type | Description |
|---|---|---|
| T | Type | Entity type |
| TU | Type | Field type, must be a numeric type, or a string or char for string concatenation |
| entity | T | Entity on which the operation should be performed. The entity should be one that was returned by the current session in a Load or Query operation, this way, the session can track down the entity's ID |
| id | string | Entity ID on which the operation should be performed. |
| path | Expression<Func<T, TU>> | Lambda describing the path to the field. |
| valToAdd | TU | Value to be added. |
Array manipulation
Session.Advanced.Patch
void Patch<T, U>(T entity, Expression<Func<T, IEnumerable<U>>> path,
Expression<Func<JavaScriptArray<U>, object>> arrayAdder);
void Patch<T, U>(string id, Expression<Func<T, IEnumerable<U>>> path,
Expression<Func<JavaScriptArray<U>, object>> arrayAdder);
| Parameters | Type | Description |
|---|---|---|
| T | Type | Entity type |
| U | Type | Type of the collection items |
| entity | T | Entity on which the operation should be performed. The entity should be one that was returned by the current session in a Load or Query operation. This way the session can track down the entity's ID. |
| id | string | Entity ID on which the operation should be performed. |
| path | Expression<Func<T, IEnumerable<U>>> | Lambda describing the path to the collection property. |
| arrayAdder | Expression<Func<JavaScriptArray<U>, object>> | Lambda that modifies the array, see JavaScriptArray below. |
Session.Advanced.AddOrPatch
void AddOrPatch<T, TU>(string id, T entity, Expression<Func<T, List<TU>>> path,
Expression<Func<JavaScriptArray<TU>, object>> arrayAdder);
| Parameters | Type | Description |
|---|---|---|
| T | Type | Entity type |
| TU | Type | Type of the list items |
| entity | T | Entity to add if no document with the given ID exists. |
| id | string | Entity ID on which the operation should be performed. |
| path | Expression<Func<T, List<TU>>> | Lambda describing the path to the list property. |
| arrayAdder | Expression<Func<JavaScriptArray<TU>, object>> | Lambda that modifies the array, see JavaScriptArray below. |
JavaScriptArray
JavaScriptArray allows building lambdas representing array manipulations for patches.
| Method Signature | Return Type | Description |
|---|---|---|
| Add(U item) | JavaScriptArray<U> | Adds one item to the array. |
| Add(params U[] items) | JavaScriptArray<U> | Adds multiple items to the array. |
| RemoveAt(int index) | JavaScriptArray<U> | Removes item in position index in array. |
| RemoveAll(Func<U, bool> predicate) | JavaScriptArray<U> | Removes all the items in the array that satisfy the given predicate. |
RemoveAtremoves exactly one item.
A negative index counts from the end only underSessionPatchBehavior.JavaScript,
whereRemoveAt(-1)removes the last item.
Under the defaultSessionPatchBehavior.JsonPatcha negative index is rejected andSaveChanges()throws,
see Differences in behavior above.
Dictionary manipulation
Session.Advanced.Patch
void Patch<T, TKey, TValue>(
T entity,
Expression<Func<T, IDictionary<TKey, TValue>>> path,
Expression<Func<JavaScriptDictionary<TKey, TValue>, object>> dictionaryAdder);
void Patch<T, TKey, TValue>(
string id,
Expression<Func<T, IDictionary<TKey, TValue>>> path,
Expression<Func<JavaScriptDictionary<TKey, TValue>, object>> dictionaryAdder);
| Parameter | Type | Description |
|---|---|---|
| T | Type | Entity type |
| TKey | Type | Dictionary key type |
| TValue | Type | Dictionary value type |
| entity | T | A tracked entity containing the dictionary property. |
| id | string | ID of the document to patch. |
| path | Expression<Func<T, IDictionary<TKey, TValue>>> | Lambda describing the path to the dictionary property. |
| dictionaryAdder | Expression<Func<JavaScriptDictionary<TKey, TValue>, object>> | Lambda that adds or removes a dictionary entry. |
JavaScriptDictionary
| Method signature | Description |
|---|---|
| Add(TKey key, TValue value) | Adds or updates a dictionary entry. |
| Add(KeyValuePair<TKey, TValue> value) | Adds or updates an entry using a key-value pair. |
| Remove(TKey key) | Removes a dictionary entry. |
Dictionary key handling
- The key is taken from the
dictionaryAdderlambda as a value, so it can be a literal,
a local variable, a captured field, or a property of another object:
var setting = new Setting { Key = "language" };
// A literal key
session.Advanced.Patch<User, string, string>("users/1",
user => user.Preferences,
preferences => preferences.Add("theme", "dark"));
// A key supplied by a variable or by another object's property
session.Advanced.Patch<User, string, string>("users/1",
user => user.Preferences,
preferences => preferences.Add(setting.Key, "en-US"));
-
A key may contain any characters, including dots, dashes, spaces, quotes, backslashes,
newlines, and emoji. The client escapes the key for whichever command format it generates:- In a JSON Patch command the key becomes a JSON Pointer segment,
with~escaped as~0and/as~1. - In a JavaScript patch command the key is written as a quoted JavaScript string literal
in bracket notation, for examplethis.Preferences["key-with-dash"] = args.val_0;
ordelete this.Preferences["key.with.dot"];.
- In a JSON Patch command the key becomes a JSON Pointer segment,
-
An empty or whitespace-only key is supported, and is applied through a JavaScript patch command.
Anullkey throwsArgumentNullException. -
Enum keys are always written as their string names, such as
"Engine",
regardless of the SaveEnumsAsIntegers convention.
TheSaveEnumsAsIntegersForPatchingconvention applies to an entry's value, not to its key.
Session API using Defer syntax
The non-typed Session API for patches uses the Session.Advanced.Defer function which allows registering one or more commands.
One of the possible commands is the PatchCommandData, describing single document patch command.
The patch request will be sent to the server only when calling SaveChanges, this way it's possible to perform multiple operations in one request to the server.
Session.Advanced.Defer
void Defer(ICommandData command, params ICommandData[] commands);
void Defer(ICommandData[] commands);
PatchCommandData
| Constructor | Type | Description |
|---|---|---|
| id | string | ID of the document to be patched. |
| changeVector | string | [Can be null] Change vector of the document to be patched, used to verify that the document was not changed before the patch reached it. |
| patch | PatchRequest | Patch request to be performed on the document. |
| patchIfMissing | PatchRequest | [Can be null] Patch request to be performed if no document with the given ID was found. |
| Property | Type | Description |
|---|---|---|
| CreateIfMissing | BlittableJsonReaderObject | [Can be null] Document to create if no document with the given ID was found, instead of running a script. |
PatchRequest
We highly recommend using scripts with parameters. This allows RavenDB to cache scripts and boost performance.
Parameters can be accessed in the script through the args object and passed using PatchRequest's "Values" parameter.
PatchRequest.Script is JavaScript. Properties accessed through this are fields in the stored document,
while properties accessed through args are values passed in PatchRequest.Values.
Property names used with this must match the stored JSON property names, including casing.
Assigning to a missing top-level property creates it, so a casing mismatch can create a second field instead of updating the intended one.
| Property | Type | Description |
|---|---|---|
| Script | string | The patching script, written in JavaScript. |
| Values | Dictionary<string, object> | Parameters to be passed to the script. Each parameter is accessed in the script as a property of args, e.g. args.FirstName. |
Operations API syntax
An operations interface that exposes the full functionality and allows performing ad-hoc patch operations without creating a session.
The methods are exposed by Raven.Client.Documents.Operations.OperationExecutor,
which is available as store.Operations.
PatchStatus Send(PatchOperation operation);
Task<PatchStatus> SendAsync(PatchOperation operation,
SessionInfo sessionInfo = null,
CancellationToken token = default(CancellationToken));
// Generic overloads, returning the document after the patch has been applied
PatchOperation.Result<TEntity> Send<TEntity>(PatchOperation<TEntity> operation,
SessionInfo sessionInfo = null);
Task<PatchOperation.Result<TEntity>> SendAsync<TEntity>(PatchOperation<TEntity> operation,
SessionInfo sessionInfo = null,
CancellationToken token = default(CancellationToken));
PatchOperation.Result<TEntity>
| Property | Type | Description |
|---|---|---|
| Status | PatchStatus | Status of the patch operation on the document. |
| Document | TEntity | The document after the patch operation completed. The document may be unchanged. |
| Constructor | Type | Description |
|---|---|---|
| id | string | ID of the document to be patched. |
| changeVector | string | Change vector of the document to be patched. Used to verify that the document was not modified before the patch reached it. Can be null. |
| patch | PatchRequest | Patch request to perform on the document. |
| patchIfMissing | PatchRequest | Patch request to perform if the specified document is not found. Will run only if no changeVector was passed.Can be null. |
| skipPatchIfChangeVectorMismatch | bool | true - do not patch if the document has been modified.false (Default) - execute the patch even if document has been modified.An exception is thrown if: this param is false + changeVector has value + document with that ID and change vector was not found. |
List of script methods syntax
This is a list of a few of the javascript methods that can be used in patch scripts.
See the more comprehensive list at Knowledge Base: JavaScript Engine.
| Method | Arguments | Description |
|---|---|---|
| load | string or string[] | Loads one or more documents into the context of the script by their document IDs |
| loadPath | A document and a path to an ID within that document | Loads a related document by the path to its ID |
| del | Document ID; change vector | Delete the given document by its ID. If you add the expected change vector and the document's current change vector does not match, the document will not be deleted. |
| put | Document ID; document; change vector | Create or overwrite a document with a specified ID and entity. If you try to overwrite an existing document and pass the expected change vector, the put will fail if the specified change vector does not match the document's current change vector. |
| cmpxchg | Key | Load a compare exchange value into the context of the script using its key |
| getMetadata | Document | Returns the document's metadata |
| id | Document | Returns the document's ID |
| lastModified | Document | Returns the DateTime of the most recent modification made to the given document |
| counter | Document; counter name | Returns the value of the specified counter in the specified document |
| counterRaw | Document; counter name | Returns the specified counter in the specified document as a key-value pair |
| incrementCounter | Document; counter name | Increases the value of the counter by one |
| deleteCounter | Document; counter name | Deletes the counter |
| spatial.distance | Two points by latitude and longitude; spatial units | Find the distance between two points on the earth |
| timeseries | Document; the time series' name | Returns the specified time series object |
| attachments | Document; attachment name | Returns an attachment object providing delete(), remote(), and copyFrom() methods for managing the specified attachment via patching |