Commands: Patches: How to use JavaScript to patch your documents?
Patch command is used to perform partial document updates without having to load, modify, and save a full document. This is usually useful for updating denormalized data in entities.
Syntax
/**
* Sends a patch request for a specific document, ignoring the document's Etag and if the document is missing
* @param key Key of the document to patch
* @param patch The patch request to use (using JavaScript)
* @return
*/
public RavenJObject patch(String key, ScriptedPatchRequest patch);
/**
* Sends a patch request for a specific document, ignoring the document's Etag
* @param key Key of the document to patch
* @param patch The patch request to use (using JavaScript)
* @param ignoreMissing true if the patch request should ignore a missing document, false to throw DocumentDoesNotExistException
* @return
*/
public RavenJObject patch(String key, ScriptedPatchRequest patch, boolean ignoreMissing);
/**
* Sends a patch request for a specific document
* @param key Key of the document to patch
* @param patch The patch request to use (using JavaScript)
* @param etag Require specific Etag [null to ignore]
* @return
*/
public RavenJObject patch(String key, ScriptedPatchRequest patch, Etag etag);
/**
* Sends a patch request for a specific document which may or may not currently exist
* @param key Id of the document to patch
* @param patchExisting The patch request to use (using JavaScript) to an existing document
* @param patchDefault The patch request to use (using JavaScript) to a default document when the document is missing
* @param defaultMetadata The metadata for the default document when the document is missing
* @return
*/
public RavenJObject patch(String key, ScriptedPatchRequest patchExisting, ScriptedPatchRequest patchDefault, RavenJObject defaultMetadata);
Parameters
public class ScriptedPatchRequest {
private String script;
private Map<String, Object> values;
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
public Map<String, Object> getValues() {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
}
Methods, objects and variables
Before we will move to the examples, let's look at the methods, objects, and variables available:
__document_id |
variable | Id for current document |
this |
object | Current document (with metadata) |
LoadDocument(key) |
method | Allows document loading, increases maximum number of allowed steps in script. See Raven/AdditionalStepsForScriptBasedOnDocumentSize here. |
PutDocument(key, data, metadata) |
method | Allows document putting, returns generated key |
IncreaseNumberOfAllowedStepsBy(number) |
method | Will increase the maximum allowed number of steps in script by given value. Only available if Raven/AllowScriptsToAdjustNumberOfSteps is set to true . |
_ |
object | Lo-Dash 2.4.1 |
trim() |
string.prototype | trims the string e.g. this.FirstName.trim() |
output(...) |
method | Allows debug your patch, prints passed messages in output tab |
indexOf(...) |
Array.prototype | wrapper for _.indexOf |
filter(...) |
Array.prototype | wrapper for _.filter |
Map(...) |
Array.prototype | wrapper for _.map |
Where(...) |
Array.prototype | wrapper for _.filter |
RemoveWhere(...) |
Array.prototype | wrapper for _.remove returning Array for easier chaining |
Remove(...) |
Array.prototype | wrapper for _.pull returning Array for easier chaining |
Custom functions
Beside built-in functions, custom ones can be introduced. Please visit this page if you want to know how to add custom functions.
Example I
// change FirstName to Robert
store.getDatabaseCommands().patch("employees/1",
new ScriptedPatchRequest("this.FirstName = 'Robert';")
);
Example II
// trim FirstName
store.getDatabaseCommands().patch("employees/1",
new ScriptedPatchRequest("this.FirstName = this.FirstName.trim();")
);
Example III
// add new property Age with value of 30
store.getDatabaseCommands().patch("employees/1",
new ScriptedPatchRequest("this.Age = 30;")
);
Example IV
// add new property Age with value of 30 using LoDash
store.getDatabaseCommands().patch("employees/1",
new ScriptedPatchRequest("_.extend(this, { 'Age': '30'});")
);
Example V
// passing data and loading different document
ScriptedPatchRequest scriptedPatchRequest =
new ScriptedPatchRequest("var employee = LoadDocument(differentEmployeeId); this.FirstName = employee.FirstName;");
Map<String, Object> params = new HashMap<>();
params.put("differentEmployeeId", "employees/2");
scriptedPatchRequest.setValues(params);
store.getDatabaseCommands().patch("employees/1", scriptedPatchRequest);
Example VI
// accessing metadata (added JavaClass property with value from @metadata)
store.getDatabaseCommands().patch("employees/1",
new ScriptedPatchRequest("this.JavaClass = this['@metadata']['Raven-Java-Type'];")
);
Example VII
// creating new document with auto-assigned key e.g. 'Comments/100'. Document key will be returned by PutDocument.
store.getDatabaseCommands().patch("employees/1",
new ScriptedPatchRequest("var commentKey = PutDocument('Comments/', { 'Author': this.LastName }, { });")
);
Example VIII
// add a new comment to Comments
store.getDatabaseCommands().patch("blogposts/1",
new ScriptedPatchRequest("this.Comments.push({ 'Title': 'Some title', 'Content': 'Lore ipsum' });")
);
Example IX
// removing comments with 'Some title' as a title
store.getDatabaseCommands().patch("blogposts/1",
new ScriptedPatchRequest("this.Comments.RemoveWhere(function(comment) { " +
" return comment.Title == 'Some title'; " +
" });"));
Example X
// modifying each comment
store.getDatabaseCommands().patch("blogposts/1",
new ScriptedPatchRequest("this.Comments.Map(function(comment) { " +
" comment.Title = 'New title'; " +
" return comment; " +
" });"));
Example XI
// increasing maximum number of allowed steps
ScriptedPatchRequest patchRequest = new ScriptedPatchRequest();
patchRequest.setScript(
"var employee = LoadDocument(differentEmployeeId);"
+ "if (employee) {"
+ " IncreaseNumberOfAllowedStepsBy(10);"
+ " this.FirstName = employee.FirstName; "
+ "}");
patchRequest.setValues(ImmutableMap.of("differentEmployeeId", (Object) "employees/2"));
store.getDatabaseCommands().patch("employees/1", patchRequest);