|
| 1 | +# Single Document Patch Operations |
| 2 | + |
| 3 | +{NOTE: } |
| 4 | +The **Patch** operation is used to perform partial document updates without having to load, modify, and save a full document. |
| 5 | +The whole operation is executed on the server side and is useful as a performance enhancement or for updating denormalized data in entities. |
| 6 | + |
| 7 | +The current page deals with patch operations on single documents. |
| 8 | + |
| 9 | +Patching has three possible interfaces: [Session API](../../../client-api/operations/patching/single-document#session-api), [Session API using defer](../../../client-api/operations/patching/single-document#session-api-using-defer), and [Operations API](../../../client-api/operations/patching/single-document#operations-api). |
| 10 | + |
| 11 | +Patching can be done from the client as well as in the studio. |
| 12 | + |
| 13 | +In this page: |
| 14 | +[API overview](../../../client-api/operations/patching/single-document#api-overview) |
| 15 | +[Examples](../../../client-api/operations/patching/single-document#examples) |
| 16 | +{NOTE/} |
| 17 | + |
| 18 | +## API overview |
| 19 | + |
| 20 | +{PANEL: Session API} |
| 21 | + |
| 22 | +A session interface that allows performing the most common patch operations. |
| 23 | +The patch request will be sent to server only when calling `saveChanges`, this way it's possible to perform multiple operations in one request to the server. |
| 24 | + |
| 25 | +### Increment Field Value |
| 26 | +`session.advanced().increment` |
| 27 | +{CODE:java patch_generic_interface_increment@ClientApi\Operations\Patches\PatchRequests.java /} |
| 28 | + |
| 29 | +| Parameters | | | |
| 30 | +| ------------- | ------------- | ----- | |
| 31 | +| **T** | `Class` | Entity class | |
| 32 | +| **U** | `Class` | Field class, must be of numeric type, or a `String` of `char` for string concatenation | |
| 33 | +| **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 | |
| 34 | +| **entity id** | `String` | Entity ID on which the operation should be performed. | |
| 35 | +| **delta** | `U` | Value to be added. | |
| 36 | + |
| 37 | +* Note how numbers are handled with the [JavaScript engine](../../../server/kb/numbers-in-ravendb) in RavenDB. |
| 38 | + |
| 39 | +### Set Field Value |
| 40 | +`session.advanced().patch` |
| 41 | +{CODE:java patch_generic_interface_set_value@ClientApi\Operations\Patches\PatchRequests.java /} |
| 42 | + |
| 43 | +| Parameters | | | |
| 44 | +| ------------- | ------------- | ----- | |
| 45 | +| **T** | `Class` | Entity Class | |
| 46 | +| **U** | `Class` | Field class | |
| 47 | +| **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 | |
| 48 | +| **entity id** | `String` | Entity ID on which the operation should be performed. | |
| 49 | +| **delta** | `U` | Value to set. | |
| 50 | + |
| 51 | +### Array Manipulation |
| 52 | +`session.advanced().patch` |
| 53 | +{CODE:java patch_generic_interface_array_modification_lambda@ClientApi\Operations\Patches\PatchRequests.java /} |
| 54 | + |
| 55 | +| Parameters | | | |
| 56 | +| ------------- | ------------- | ----- | |
| 57 | +| **T** | `Class` | Entity class | |
| 58 | +| **U** | `Class` | Field class | |
| 59 | +| **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 | |
| 60 | +| **entity id** | `String` | Entity ID on which the operation should be performed. | |
| 61 | +| **arrayAdder** | `Consumer<JavaScriptArray<U>>` | Lambda that modifies the array, see `JavaScriptArray` below. | |
| 62 | + |
| 63 | +{INFO:JavaScriptArray} |
| 64 | +`JavaScriptArray` allows building lambdas representing array manipulations for patches. |
| 65 | + |
| 66 | +| Method Signature| Return Type | Description | |
| 67 | +|--------|:-----|-------------| |
| 68 | +| **put(T item)** | `JavaScriptArray` | Allows adding `item` to an array. | |
| 69 | +| **put(T... items)** | `JavaScriptArray` | Items to be added to the array. | |
| 70 | +| **put(Collection<T> items)** | `JavaScriptArray` | Items to be added to the array. | |
| 71 | +| **removeAt(int index)** | `JavaScriptArray` | Removes item in position `index` in array. | |
| 72 | + |
| 73 | +{INFO/} |
| 74 | + |
| 75 | +{PANEL/} |
| 76 | + |
| 77 | +{PANEL:Session API using defer} |
| 78 | +The low level session api for patches uses the `session.advanced().defer` function that allows registering single or several commands. |
| 79 | +One of the possible commands is the `PatchCommandData`, describing single document patch command. |
| 80 | +The patch request will be sent to server only when calling `saveChanges`, this way it's possible to perform multiple operations in one request to the server. |
| 81 | + |
| 82 | +`session.advanced().defer` |
| 83 | +{CODE:java patch_non_generic_interface_in_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 84 | + |
| 85 | +{INFO: PatchCommandData} |
| 86 | + |
| 87 | +| Constructor| | | |
| 88 | +|--------|:-----|-------------| |
| 89 | +| **id** | `String` | ID of the document to be patched. | |
| 90 | +| **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. | |
| 91 | +| **patch** | `PatchRequest` | Patch request to be performed on the document. | |
| 92 | +| **patchIfMissing** | `PatchRequest` | [Can be null] Patch request to be performed if no document with the given ID was found. | |
| 93 | + |
| 94 | +{INFO/} |
| 95 | + |
| 96 | +{INFO: PatchRequest} |
| 97 | + |
| 98 | +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. |
| 99 | + |
| 100 | +| Members | | | |
| 101 | +| ------------- | ------------- | ----- | |
| 102 | +| **Script** | `String` | JavaScript code to be run. | |
| 103 | +| **Values** | `Map<String, Object>` | Parameters to be passed to the script. The parameters can be accessed using the '$' prefix. Parameter starting with a '$' will be used as is, without further concatenation . | |
| 104 | + |
| 105 | +{INFO/} |
| 106 | + |
| 107 | +{PANEL/} |
| 108 | + |
| 109 | + |
| 110 | +{PANEL: Operations API} |
| 111 | +An operations interface that exposes the full functionality and allows performing ad-hoc patch operations without creating a session. |
| 112 | + |
| 113 | +{CODE:java patch_non_generic_interface_in_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 114 | + |
| 115 | +{INFO: PatchOperation} |
| 116 | + |
| 117 | +| Constructor| | | |
| 118 | +|--------|:-----|-------------| |
| 119 | +| **id** | `String` | ID of the document to be patched. | |
| 120 | +| **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. | |
| 121 | +| **patch** | `PatchRequest` | Patch request to be performed on the document. | |
| 122 | +| **patchIfMissing** | `PatchRequest` | [Can be null] Patch request to be performed if no document with the given ID was found. Will run only if no `changeVector` was passed. | |
| 123 | +| **skipPatchIfChangeVectorMismatch** | `boolean` | If false and `changeVector` has value, and document with that ID and change vector was not found, will throw exception. | |
| 124 | + |
| 125 | +{INFO/} |
| 126 | + |
| 127 | +{PANEL/} |
| 128 | + |
| 129 | +{PANEL: List of Script Methods} |
| 130 | + |
| 131 | +This is a list of a few of the javascript methods that can be used in patch scripts. See the |
| 132 | +more comprehensive list at [Knowledge Base: JavaScript Engine](../../../server/kb/javascript-engine#predefined-javascript-functions). |
| 133 | + |
| 134 | +| Method | Arguments | Description | |
| 135 | +| - | - | - | |
| 136 | +| **load** | `string` or `string[]` | Loads one or more documents into the context of the script by their document IDs | |
| 137 | +| **loadPath** | A document and a path to an ID within that document | Loads a related document by the path to its ID | |
| 138 | +| **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. | |
| 139 | +| **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. | |
| 140 | +| **cmpxchg** | Key | Load a compare exchange value into the context of the script using its key | |
| 141 | +| **getMetadata** | Document | Returns the document's metadata | |
| 142 | +| **id** | Document | Returns the document's ID | |
| 143 | +| **lastModified** | Document | Returns the `DateTime` of the most recent modification made to the given document | |
| 144 | +| **counter** | Document; counter name | Returns the value of the specified counter in the specified document | |
| 145 | +| **counterRaw** | Document; counter name | Returns the specified counter in the specified document as a key-value pair | |
| 146 | +| **incrementCounter** | Document; counter name | Increases the value of the counter by one | |
| 147 | +| **deleteCounter** | Document; counter name | Deletes the counter | |
| 148 | + |
| 149 | +{PANEL/} |
| 150 | + |
| 151 | +{PANEL: Examples} |
| 152 | + |
| 153 | +###Change Field's Value |
| 154 | + |
| 155 | +{CODE-TABS} |
| 156 | +{CODE-TAB:java:Session-syntax patch_firstName_generic@ClientApi\Operations\Patches\PatchRequests.java /} |
| 157 | +{CODE-TAB:java:Session-defer-syntax patch_firstName_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 158 | +{CODE-TAB:java:Operations-syntax patch_firstName_non_generic_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 159 | +{CODE-TABS/} |
| 160 | + |
| 161 | +###Change Values of Two Fields |
| 162 | + |
| 163 | +{CODE-TABS} |
| 164 | +{CODE-TAB:java:Session-syntax patch_firstName_and_lastName_generic@ClientApi\Operations\Patches\PatchRequests.java /} |
| 165 | +{CODE-TAB:java:Session-defer-syntax pathc_firstName_and_lastName_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 166 | +{CODE-TAB:java:Operations-syntax pathc_firstName_and_lastName_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 167 | +{CODE-TABS/} |
| 168 | + |
| 169 | +###Increment Value |
| 170 | + |
| 171 | +{CODE-TABS} |
| 172 | +{CODE-TAB:java:Session-syntax increment_age_generic@ClientApi\Operations\Patches\PatchRequests.java /} |
| 173 | +{CODE-TAB:java:Session-defer-syntax increment_age_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 174 | +{CODE-TAB:java:Operations-syntax increment_age_non_generic_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 175 | +{CODE-TABS/} |
| 176 | + |
| 177 | +###Add Item to Array |
| 178 | + |
| 179 | +{CODE-TABS} |
| 180 | +{CODE-TAB:java:Session-syntax add_new_comment_to_comments_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 181 | +{CODE-TAB:java:Session-defer-syntax add_new_comment_to_comments_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 182 | +{CODE-TAB:java:Operations-syntax add_new_comment_to_comments_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 183 | +{CODE-TABS/} |
| 184 | + |
| 185 | +###Insert Item into Specific Position in Array |
| 186 | + |
| 187 | +Inserting item into specific position is supported only by the non-typed APIs |
| 188 | +{CODE-TABS} |
| 189 | +{CODE-TAB:java:Session-defer-syntax insert_new_comment_at_position_1_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 190 | +{CODE-TAB:java:Operations-syntax insert_new_comment_at_position_1_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 191 | +{CODE-TABS/} |
| 192 | + |
| 193 | +###Modify Item in Specific Position in Array |
| 194 | + |
| 195 | +Inserting item into specific position is supported only by the non-typed APIs |
| 196 | +{CODE-TABS} |
| 197 | +{CODE-TAB:java:Session-defer-syntax modify_a_comment_at_position_3_in_comments_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 198 | +{CODE-TAB:java:Operations-syntax modify_a_comment_at_position_3_in_comments_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 199 | +{CODE-TABS/} |
| 200 | + |
| 201 | +###Remove Items from Array |
| 202 | + |
| 203 | +Filtering items from an array supported only by the non-typed APIs |
| 204 | +{CODE-TABS} |
| 205 | +{CODE-TAB:java:Session-defer-syntax filter_items_from_array_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 206 | +{CODE-TAB:java:Operations-syntax filter_items_from_array_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 207 | +{CODE-TABS/} |
| 208 | + |
| 209 | +###Loading Documents in a Script |
| 210 | + |
| 211 | +Loading documents supported only by non-typed APIs |
| 212 | +{CODE-TABS} |
| 213 | +{CODE-TAB:java:Session-defer-syntax update_product_name_in_order_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 214 | +{CODE-TAB:java:Operations-syntax update_product_name_in_order_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 215 | +{CODE-TABS/} |
| 216 | + |
| 217 | +###Remove Property |
| 218 | + |
| 219 | +Removing property supported only by the non-typed APIs |
| 220 | +{CODE-TABS} |
| 221 | +{CODE-TAB:java:Session-defer-syntax rename_property_age_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 222 | +{CODE-TAB:java:Operations-syntax rename_property_age_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 223 | +{CODE-TABS/} |
| 224 | + |
| 225 | +###Rename Property |
| 226 | + |
| 227 | +Renaming property supported only by the non-typed APIs |
| 228 | +{CODE-TABS} |
| 229 | +{CODE-TAB:java:Session-defer-syntax rename_property_age_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 230 | +{CODE-TAB:java:Operations-syntax rename_property_age_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 231 | +{CODE-TABS/} |
| 232 | + |
| 233 | +###Add Document |
| 234 | + |
| 235 | +Adding a new document is supported only by the non-typed APIs |
| 236 | +{CODE-TABS} |
| 237 | +{CODE-TAB:java:Session-defer-syntax add_document_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 238 | +{CODE-TAB:java:Operations-syntax add_document_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 239 | +{CODE-TABS/} |
| 240 | + |
| 241 | +###Clone Document |
| 242 | + |
| 243 | +In order to clone a document use put method as follows |
| 244 | +{CODE-TABS} |
| 245 | +{CODE-TAB:java:Session-defer-syntax clone_document_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 246 | +{CODE-TAB:java:Operations-syntax clone_document_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 247 | +{CODE-TABS/} |
| 248 | + |
| 249 | +{INFO: } |
| 250 | + |
| 251 | +__Attachments, Counters, Time Series, and Revisions:__ |
| 252 | + |
| 253 | +Attachments, counters, time series data, and revisions from the source document will Not be copied to the new document automatically. |
| 254 | + |
| 255 | +{INFO/} |
| 256 | + |
| 257 | +###Increment Counter |
| 258 | + |
| 259 | +In order to increment or create a counter use <code>incrementCounter</code> method as follows |
| 260 | +{CODE-TABS} |
| 261 | +{CODE-TAB:java:Session-defer-syntax increment_counter_by_document_id_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 262 | +{CODE-TAB:java:Operations-syntax increment_counter_by_document_id_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 263 | +{CODE-TABS/} |
| 264 | + |
| 265 | +{INFO:Method Overloading & Value restrictions} |
| 266 | +The method can be called by document ID or by document reference and the value can be negative |
| 267 | +{INFO/} |
| 268 | + |
| 269 | +###Delete Counter |
| 270 | + |
| 271 | +In order to delete a counter use <code>deleteCounter</code> method as follows |
| 272 | +{CODE-TABS} |
| 273 | +{CODE-TAB:java:Session-defer-syntax delete_counter_by_document_refference_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 274 | +{CODE-TAB:java:Operations-syntax delete_counter_by_document_refference_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 275 | +{CODE-TABS/} |
| 276 | + |
| 277 | +{INFO:Method Overloading} |
| 278 | +The method can be called by document ID or by document reference |
| 279 | +{INFO/} |
| 280 | + |
| 281 | +###Get Counter |
| 282 | + |
| 283 | +In order to get a counter while patching use <code>counter</code> method as follows |
| 284 | +{CODE-TABS} |
| 285 | +{CODE-TAB:java:Session-defer-syntax get_counter_by_document_id_non_generic_session@ClientApi\Operations\Patches\PatchRequests.java /} |
| 286 | +{CODE-TAB:java:Operations-syntax get_counter_by_document_id_store@ClientApi\Operations\Patches\PatchRequests.java /} |
| 287 | +{CODE-TABS/} |
| 288 | + |
| 289 | +{INFO:Method Overloading} |
| 290 | +The method can be called by document ID or by document reference |
| 291 | +{INFO/} |
| 292 | + |
| 293 | +{PANEL/} |
| 294 | + |
| 295 | +## Related Articles |
| 296 | + |
| 297 | +### Patching |
| 298 | + |
| 299 | +- [Set based patch operation](../../../client-api/operations/patching/set-based) |
| 300 | + |
| 301 | +### Knowledge Base |
| 302 | + |
| 303 | +- [JavaScript engine](../../../server/kb/javascript-engine) |
| 304 | +- [Numbers in JavaScript engine](../../../server/kb/numbers-in-ravendb#numbers-in-javascript-engine) |
0 commit comments