diff --git a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.dotnet.markdown index e0c3a720b8..d8546bd447 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.dotnet.markdown @@ -36,10 +36,11 @@ In this page: {CODE patchBeQueryOperationCtor2@Common.cs /} -| Parameter | | | -| ------------- | ------------- | ----- | -| **queryToUpdate** | `string` or `IndexQuery` | RQL query defining the update operation. The RQL query starts as any other RQL query with "from" and "update" statements. Later, it continues with an "update" clause in which you describe the Javascript patch code -| **options** | `QueryOperationOptions` | Options defining how the operation will be performed and various constraints on how it is performed +| Parameter | Type | Description | +|-------------------|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **queryToUpdate** | `string` | The query & patch definition.
The RQL query starts as any other RQL query with a "from" statement.
It continues with an "update" clause that contains the Javascript patching code. | +| **queryToUpdate** | `IndexQuery` | Object containing the query & the patching string,
with the option to use parameters. | +| **options** | `QueryOperationOptions` | Options defining how the operation will be performed and various constraints on how it is performed.
Default: `null` | {PANEL/} diff --git a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.js.markdown index 58649bd57f..af06d3ab51 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/set-based.js.markdown @@ -204,11 +204,11 @@ update { {CODE:nodejs syntax_2@client-api\operations\patches\setBasedPatchRequests.js /} -| Parameter | Type | Description | -|-------------------|--------------|------------------------------------------------------------| -| __queryToUpdate__ | `string` | The query & patch definition. | -| __queryToUpdate__ | `IndexQuery` | Object that allows adding parameters to the query & patch. | -| __options__ | `object` | Options for the _PatchByQueryOperation_. | +| Parameter | Type | Description | +|-------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| __queryToUpdate__ | `string` | The query & patch definition.
The RQL query starts as any other RQL query with a "from" statement.
It continues with an "update" clause that contains the Javascript patching code. | +| __queryToUpdate__ | `IndexQuery` | Object containing the query & the patching string,
with the option to use parameters. | +| __options__ | `object` | Options for the _PatchByQueryOperation_. | {CODE:nodejs syntax_3@client-api\operations\patches\setBasedPatchRequests.js /} diff --git a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.dotnet.markdown index 7f7c82e084..5fd9ac186d 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.dotnet.markdown @@ -185,7 +185,9 @@ The patch request will be sent to the server only when calling `SaveChanges`, th `Session.Advanced.Defer` {CODE patch_non_generic_interface_in_session@ClientApi\Operations\Patches\PatchRequests.cs /} -{INFO: PatchCommandData} +{INFO: } + +#### PatchCommandData | Constructor | Type | Description | |--------------------|----------------|------------------------------------------------------------------------------------------------------------------------------------------| @@ -196,15 +198,17 @@ The patch request will be sent to the server only when calling `SaveChanges`, th {INFO/} -{INFO: PatchRequest} +{INFO: } + +#### 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. -| Members | Type | Description | -|------------|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Script** | `string` | JavaScript code to be run. | -| **Values** | `Dictionary` | 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. | +| Property | Type | Description | +|------------|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Script** | `string` | The patching script, written in JavaScript. | +| **Values** | `Dictionary` | 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. | {INFO/} @@ -221,13 +225,13 @@ An operations interface that exposes the full functionality and allows performin {INFO: PatchOperation} -| 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. Will run only if no `changeVector` was passed. | -| **skipPatchIfChangeVectorMismatch** | `bool` | If false and `changeVector` has value, and document with that ID and change vector was not found, will throw an exception. | +| 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. | {INFO/} diff --git a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.js.markdown index 010b2cac48..577dc0a3c3 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/client-api/operations/patching/single-document.js.markdown @@ -499,13 +499,13 @@ Learn more about Counters in this [Counters Overview](../../../document-extensio {CODE:nodejs operations_syntax@client-api\operations\patches\patchRequests.js /} -| Constructor | Type | Description | -|-------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| __id__ | `string` | ID of document to be patched. | -| __changeVector__ | `string` | Change vector of the document to be patched.
Used to verify that the document was not changed before the patch is executed. Can be null. | -| __patch__ | `PatchRequest` | Patch request to be performed on the document. | -| __patchIfMissing__ | `PatchRequest` | Patch request to be performed if no document with the given ID was found. Will run only if no `changeVector` was passed. Can be null. | -| __skipPatchIfChangeVectorMismatch__ | `boolean` | An exception is thrown if:
this param is `false` + `changeVector` has value + document with that ID and change vector was not found. | +| 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 is executed. 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__ | `boolean` | `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. | --- diff --git a/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/patch.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/patch.dotnet.markdown new file mode 100644 index 0000000000..b1c196fe3c --- /dev/null +++ b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/patch.dotnet.markdown @@ -0,0 +1,175 @@ +# Patch Time Series Operations + +--- + +{NOTE: } + + +* Patching time series data (Append or Delete entries) can be performed via [Operations](../../../../client-api/operations/what-are-operations). + * Use [PatchOperation](../../../../client-api/operations/patching/single-document) to patch data on a **single** document. + * Use [PatchByQueryOperation](../../../../client-api/operations/patching/set-based) to patch data on **multiple** documents. + +* Patching time series entries on a single document can also be performed via the [Session](../../../../document-extensions/timeseries/client-api/session/patch). + +* In this page: + * [Patch time series data - single document](../../../../document-extensions/timeseries/client-api/operations/patch#patch-time-series-data---single-document) + * [Usage](../../../../document-extensions/timeseries/client-api/operations/patch#usage) + * [Examples](../../../../document-extensions/timeseries/client-api/operations/patch#examples) + * [Syntax](../../../../document-extensions/timeseries/client-api/operations/patch#syntax) + * [Patch time series data - multiple documents](../../../../document-extensions/timeseries/client-api/operations/patch#patch-time-series-data---multiple-documents) + * [Usage](../../../../document-extensions/timeseries/client-api/operations/patch#usage-1) + * [Examples](../../../../document-extensions/timeseries/client-api/operations/patch#examples-1) + * [Syntax](../../../../document-extensions/timeseries/client-api/operations/patch#syntax-1) + +{NOTE/} + +--- + +{PANEL: Patch time series data - single document} + +--- + +### Usage + +* Create a `PatchRequest` instance: + * Define the Append or Delete action using the [JavaScript time series API](../../../../document-extensions/timeseries/client-api/javascript-support). + +* Create a `PatchOperation` instance and pass it: + * The ID of the document to patch + * The document change vector (or `null`) + * The `PatchRequest` object + +* Execute the `PatchOperation` operation by calling `store.Operations.Send` + +* NOTE: + * The server treats timestamps passed in the patch request script as **UTC**, no conversion is applied by the client to local time. + * Appending entries to a time series that doesn't yet exist yet will create the time series. + * No exception is thrown if the specified document does not exist. + +--- + +### Examples + +{NOTE: } + +In this example, we **append** a single entry to time series "HeartRates" on the specified document. + +{CODE TS_region-Operation_Patch-Append-Single-TS-Entry@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + +In this example, we **append** 100 entries to time series "HeartRates" on the specified document. +Timestamps and values are drawn from an array and other arguments are provided in the "Values" property. + +{CODE TS_region-Operation_Patch-Append-100-TS-Entries@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + +In this example, we **delete** a range of 50 entries from time series "HeartRates" on the specified document. + +{CODE TS_region-Operation_Patch-Delete-50-TS-Entries@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +--- + +### Syntax + +* The detailed syntax of `PatchOperation` is listed under this [syntax section](../../../../client-api/operations/patching/single-document#operations-api). + +* The detailed syntax of `PatchRequest` is listed under this [syntax section](../../../../client-api/operations/patching/single-document#patchrequest). + +* The available JavaScript API methods are detailed in the [time series JavaScript support](../../../../document-extensions/timeseries/client-api/javascript-support) article. + +{PANEL/} + +{PANEL: Patch time series data - multiple documents} + +--- + +### Usage + +* In order to patch time series data on multiple documents, you need to: + * Define a query that retrieves the set of documents to be patched (can be a dynamic or an index query). + * Define the patching action that will be executed on the matching documents. + +* This is achieved by defining a string, or creating an instance of `IndexQuery` that contains such string, + with the following two parts: + * **The query**: provide an [RQL](../../../../client-api/session/querying/what-is-rql) code snippet to filter the documents you want to patch. + * **The patching script**: use the [JavaScript time series API](../../../../document-extensions/timeseries/client-api/javascript-support) to define the patching action. + +* Create a `PatchByQueryOperation` instance and pass it the `IndexQuery` object, or the defined string. + +* Execute the `PatchByQueryOperation` by calling `store.Operations.Send`. + * The patch operation will be executed only on documents that match the query. + * This type of operation can be awaited for completion. Learn more in [Manage length operations](../../../../client-api/operations/what-are-operations#manage-lengthy-operations). + +* NOTE: + * The server treats timestamps passed in the patch request script as **UTC**, no conversion is applied. + * No exception is thrown if any of the documents no longer exist during patching. + +--- + +### Examples + +{NOTE: } + +In this example, we **append** an entry to time series "HeartRates" on ALL documents in the "Users" collection. + +{CODE TS_region-PatchByQueryOperation-Append-To-Multiple-Docs@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + +In this example, we **delete** the "HeartRates" time series from documents that match the query criteria. + +{CODE TS_region-PatchByQueryOperation-Delete-From-Multiple-Docs@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + +* In this example, for each document in the "Users" collection, we patch a document field with data retrieved from its time series entries. + The document's time series data itself is Not patched. + +* The document field "NumberOfUniqueTagsInTS" will be updated with the number of unique tags in the user's "HeartRates" time series. + +* To do this, we use the JavaScript [get](../../../../document-extensions/timeseries/client-api/javascript-support#section-3) method to get all the time series entries for each document + and extract each entry's tag. + +{CODE TS_region-PatchByQueryOperation-Get@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +--- + +### Syntax + +* The detailed syntax of `PatchByQueryOperation` is listed under this [syntax section](../../../../client-api/operations/patching/set-based#syntax-overview). + +* The available JavaScript API methods are detailed in the [time series JavaScript support](../../../../document-extensions/timeseries/client-api/javascript-support) article. + +{PANEL/} + +## Related articles + +**Time Series and JavaScript** +[The Time Series JavaScript API](../../../../document-extensions/timeseries/client-api/javascript-support) + +**Client API** +[Time Series API Overview](../../../../document-extensions/timeseries/client-api/overview) + +**Studio Articles** +[Studio Time Series Management](../../../../studio/database/document-extensions/time-series) + +**Querying and Indexing** +[Time Series Querying](../../../../document-extensions/timeseries/querying/overview-and-syntax) +[Time Series Indexing](../../../../document-extensions/timeseries/indexing) + +**Policies** +[Time Series Rollup and Retention](../../../../document-extensions/timeseries/rollup-and-retention) diff --git a/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/patch.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/patch.js.markdown new file mode 100644 index 0000000000..4d4f2ff5c3 --- /dev/null +++ b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/patch.js.markdown @@ -0,0 +1,175 @@ +# Patch Time Series Operations + +--- + +{NOTE: } + + +* Patching time series data (Append or Delete entries) can be performed via [Operations](../../../../client-api/operations/what-are-operations). + * Use [PatchOperation](../../../../client-api/operations/patching/single-document) to patch data on a **single** document. + * Use [PatchByQueryOperation](../../../../client-api/operations/patching/set-based) to patch data on **multiple** documents. + +* Patching time series entries on a single document can also be performed via the [session](../../../../document-extensions/timeseries/client-api/session/patch). + +* In this page: + * [Patch time series data - single document](../../../../document-extensions/timeseries/client-api/operations/patch#patch-time-series-data---single-document) + * [Usage](../../../../document-extensions/timeseries/client-api/operations/patch#usage) + * [Examples](../../../../document-extensions/timeseries/client-api/operations/patch#examples) + * [Syntax](../../../../document-extensions/timeseries/client-api/operations/patch#syntax) + * [Patch time series data - multiple documents](../../../../document-extensions/timeseries/client-api/operations/patch#patch-time-series-data---multiple-documents) + * [Usage](../../../../document-extensions/timeseries/client-api/operations/patch#usage-1) + * [Examples](../../../../document-extensions/timeseries/client-api/operations/patch#examples-1) + * [Syntax](../../../../document-extensions/timeseries/client-api/operations/patch#syntax-1) + +{NOTE/} + +--- + +{PANEL: Patch time series data - single document} + +--- + +### Usage + +* Create a `PatchRequest` instance: + * Define the Append or Delete action using the [JavaScript time series API](../../../../document-extensions/timeseries/client-api/javascript-support). + +* Create a `PatchOperation` instance and pass it: + * The ID of the document to patch + * The document change vector (or `null`) + * The `PatchRequest` object + +* Execute the `PatchOperation` operation by calling `store.operations.send` + +* NOTE: + * The server treats timestamps passed in the patch request script as **UTC**, no conversion is applied by the client to local time. + * Appending entries to a time series that doesn't yet exist yet will create the time series. + * No exception is thrown if the specified document does not exist. + +--- + +### Examples + +{NOTE: } + +In this example, we **append** a single entry to time series "HeartRates" on the specified document. + +{CODE:nodejs patch_1@documentExtensions\timeSeries\client-api\patchOperations.js /} + +{NOTE/} + +{NOTE: } + +In this example, we **append** 100 entries to time series "HeartRates" on the specified document. +Timestamps and values are drawn from an array and other arguments are provided in the "values" property. + +{CODE:nodejs patch_2@documentExtensions\timeSeries\client-api\patchOperations.js /} + +{NOTE/} + +{NOTE: } + +In this example, we **delete** a range of 50 entries from time series "HeartRates" on the specified document. + +{CODE:nodejs patch_3@documentExtensions\timeSeries\client-api\patchOperations.js /} + +{NOTE/} + +--- + +### Syntax + +* The detailed syntax of `PatchOperation` is listed under this [syntax section](../../../../client-api/operations/patching/single-document#operations-api-syntax). + +* The detailed syntax of `PatchRequest` is listed under this [syntax section](../../../../client-api/operations/patching/single-document#session-api-using-defer-syntax). + +* The available JavaScript API methods are detailed in the [time series JavaScript support](../../../../document-extensions/timeseries/client-api/javascript-support) article. + +{PANEL/} + +{PANEL: Patch time series data - multiple documents} + +--- + +### Usage + +* In order to patch time series data on multiple documents, you need to: + * Define a query that retrieves the set of documents to be patched (can be a dynamic or an index query). + * Define the patching action that will be executed on the matching documents. + +* This is achieved by defining a string, or creating an instance of `IndexQuery` that contains such string, + with the following two parts: + * **The query**: provide an [RQL](../../../../client-api/session/querying/what-is-rql) code snippet to filter the documents you want to patch. + * **The patching script**: use the [JavaScript time series API](../../../../document-extensions/timeseries/client-api/javascript-support) to define the patching action. + +* Create a `PatchByQueryOperation` instance and pass it the `IndexQuery` object, or the defined string. + +* Execute the `PatchByQueryOperation` by calling `store.operations.send`. + * The patch operation will be executed only on documents that match the query. + * This type of operation can be awaited for completion. Learn more in [Manage length operations](../../../../client-api/operations/what-are-operations#manage-lengthy-operations). + +* NOTE: + * The server treats timestamps passed in the patch request script as **UTC**, no conversion is applied. + * No exception is thrown if any of the documents no longer exist during patching. + +--- + +### Examples + +{NOTE: } + +In this example, we **append** an entry to time series "HeartRates" on ALL documents in the "Users" collection. + +{CODE:nodejs patch_4@documentExtensions\timeSeries\client-api\patchOperations.js /} + +{NOTE/} + +{NOTE: } + +In this example, we **delete** the "HeartRates" time series from documents that match the query criteria. + +{CODE:nodejs patch_5@documentExtensions\timeSeries\client-api\patchOperations.js /} + +{NOTE/} + +{NOTE: } + +* In this example, for each document in the "Users" collection, we patch a document field with data retrieved from its time series entries. + The document's time series data itself is Not patched. + +* The document field "numberOfUniqueTagsInTS" will be updated with the number of unique tags in the user's "HeartRates" time series. + +* To do this, we use the JavaScript [get](../../../../document-extensions/timeseries/client-api/javascript-support#section-3) method to get all the time series entries for each document + and extract each entry's tag. + +{CODE:nodejs patch_6@documentExtensions\timeSeries\client-api\patchOperations.js /} + +{NOTE/} + +--- + +### Syntax + +* The detailed syntax of `PatchByQueryOperation` is listed under this [syntax section](../../../../client-api/operations/patching/set-based#patchbyqueryoperation-syntax). + +* The available JavaScript API methods are detailed in the [time series JavaScript support](../../../../document-extensions/timeseries/client-api/javascript-support) article. + +{PANEL/} + +## Related articles + +**Time Series and JavaScript** +[The Time Series JavaScript API](../../../../document-extensions/timeseries/client-api/javascript-support) + +**Client API** +[Time Series API Overview](../../../../document-extensions/timeseries/client-api/overview) + +**Studio Articles** +[Studio Time Series Management](../../../../studio/database/document-extensions/time-series) + +**Querying and Indexing** +[Time Series Querying](../../../../document-extensions/timeseries/querying/overview-and-syntax) +[Time Series Indexing](../../../../document-extensions/timeseries/indexing) + +**Policies** +[Time Series Rollup and Retention](../../../../document-extensions/timeseries/rollup-and-retention) diff --git a/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs b/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs index 35b66a6c67..2df3994b44 100644 --- a/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs +++ b/Documentation/5.4/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs @@ -1166,12 +1166,10 @@ public void PatchSingleEntryUsingSessionDefer() } }, null)); session.SaveChanges(); - } } } - // patching a document a single time-series entry // using PatchOperation [Fact] @@ -1191,25 +1189,32 @@ public void PatchSingleEntryUsingPatchOperation() } #region TS_region-Operation_Patch-Append-Single-TS-Entry - var baseline = DateTime.Today; - - store.Operations.Send(new PatchOperation("users/1-A", null, - new PatchRequest + var baseTime = DateTime.UtcNow; + + var patchRequest = new PatchRequest + { + // Define the patch request using JavaScript: + Script = "timeseries(this, $timeseries).append($timestamp, $values, $tag);", + + // Provide values for the parameters in the script: + Values = { - Script = "timeseries(this, $timeseries).append($timestamp, $values, $tag);", - Values = - { - { "timeseries", "HeartRates" }, - { "timestamp", baseline.AddMinutes(1) }, - { "values", 59d }, - { "tag", "watches/fitbit" } - } - })); + { "timeseries", "HeartRates" }, + { "timestamp", baseTime.AddMinutes(1) }, + { "values", 59d }, + { "tag", "watches/fitbit" } + } + }; + + // Define the patch operation; + var patchOp = new PatchOperation("users/john", null, patchRequest); + + // Execute the operation: + store.Operations.Send(patchOp); #endregion } } - // Patching: Append and Remove multiple time-series entries // Using session.Advanced.Defer [Fact] @@ -1376,60 +1381,57 @@ public void PatcAndhDeleteMultipleEntriesOperation() using (var session = store.OpenSession()) { #region TS_region-Operation_Patch-Append-100-TS-Entries - var baseline = DateTime.Today; + var baseTime = DateTime.UtcNow; // Create arrays of timestamps and random values to patch - List values = new List(); - List timeStamps = new List(); + var values = new List(); + var timeStamps = new List(); - for (var cnt = 0; cnt < 100; cnt++) + for (var i = 0; i < 100; i++) { values.Add(68 + Math.Round(19 * new Random().NextDouble())); - timeStamps.Add(baseline.AddSeconds(cnt)); + timeStamps.Add(baseTime.AddMinutes(i)); } - store.Operations.Send(new PatchOperation("users/1-A", null, - new PatchRequest + var patchRequest = new PatchRequest + { + Script = @"var i = 0; + for (i = 0; i < $values.length; i++) { + timeseries(id(this), $timeseries).append ( + $timeStamps[i], + $values[i], + $tag); + }", + Values = { - Script = @"var i = 0; - for (i = 0; i < $values.length; i++) - {timeseries(id(this), $timeseries) - .append ( - new Date($timeStamps[i]), - $values[i], - $tag); - }", - Values = - { - { "timeseries", "HeartRates" }, - { "timeStamps", timeStamps}, - { "values", values }, - { "tag", "watches/fitbit" } - } + { "timeseries", "HeartRates" }, + { "timeStamps", timeStamps }, + { "values", values }, + { "tag", "watches/fitbit" } + } + }; - })); + var patchOp = new PatchOperation("users/john", null, patchRequest); + store.Operations.Send(patchOp); #endregion #region TS_region-Operation_Patch-Delete-50-TS-Entries - store.Operations.Send(new PatchOperation("users/1-A", null, + store.Operations.Send(new PatchOperation("users/john", null, new PatchRequest { Script = "timeseries(this, $timeseries).delete($from, $to);", Values = { { "timeseries", "HeartRates" }, - { "from", baseline.AddSeconds(0) }, - { "to", baseline.AddSeconds(49) } + { "from", baseTime }, + { "to", baseTime.AddMinutes(49) } } })); #endregion - } } } - - //Query Time-Series Using Raw RQL [Fact] public void QueryTimeSeriesUsingRawRQL() @@ -2218,21 +2220,30 @@ public async Task PatchTimeSerieshByQuery() var baseline = DateTime.Today; #region TS_region-PatchByQueryOperation-Append-To-Multiple-Docs - PatchByQueryOperation appendRestHeartRateOperation = new PatchByQueryOperation(new IndexQuery + var indexQuery = new IndexQuery { - Query = @"from Users as u update - { - timeseries(u, $name).append($time, $values, $tag) - }", + // Define the query and the patching action that follows the 'update' keyword: + Query = @"from Users as u + update + { + timeseries(u, $name).append($time, $values, $tag) + }", + + // Provide values for the parameters in the script: QueryParameters = new Parameters - { - { "name", "RestHeartRate" }, - { "time", baseline.AddMinutes(1) }, - { "values", new[]{59d} }, - { "tag", "watches/fitbit1" } - } - }); - store.Operations.Send(appendRestHeartRateOperation); + { + { "name", "HeartRates" }, + { "time", baseline.AddMinutes(1) }, + { "values", new[] {59d} }, + { "tag", "watches/fitbit" } + } + }; + + // Define the patch operation: + var patchByQueryOp = new PatchByQueryOperation(indexQuery); + + // Execute the operation: + store.Operations.Send(patchByQueryOp); #endregion // Append time series to multiple documents @@ -2308,14 +2319,15 @@ from Users as u var result = store.Operations.Send(getExerciseHeartRateOperation).WaitForCompletion(); #region TS_region-PatchByQueryOperation-Delete-From-Multiple-Docs - PatchByQueryOperation deleteOperation = new PatchByQueryOperation(new IndexQuery + PatchByQueryOperation deleteByQueryOp = new PatchByQueryOperation(new IndexQuery { Query = @"from Users as u - where u.age < 30 + where u.Age < 30 update { timeseries(u, $name).delete($from, $to) }", + QueryParameters = new Parameters { { "name", "HeartRates" }, @@ -2324,7 +2336,9 @@ where u.age < 30 } }); - store.Operations.Send(deleteOperation); + // Execute the operation: + // Time series "HeartRates" will be deleted for all users with age < 30 + store.Operations.Send(deleteByQueryOp); #endregion } } @@ -2396,43 +2410,43 @@ public async Task PatchTimeSerieshByQueryWithGet() session.SaveChanges(); } - #region TS_region-PatchByQueryOperation-Get - PatchByQueryOperation patchNumOfUniqueTags = new PatchByQueryOperation(new IndexQuery + #region TS_region-PatchByQueryOperation-Get + PatchByQueryOperation patchNumberOfUniqueTags = new PatchByQueryOperation(new IndexQuery { Query = @" - declare function foo(doc){ - var entries = timeseries(doc, $name).get($from, $to); - var differentTags = []; - for (var i = 0; i < entries.length; i++) - { - var e = entries[i]; - if (e.Tag !== null) - { - if (!differentTags.includes(e.Tag)) - { - differentTags.push(e.Tag); - } - } - } - doc.NumberOfUniqueTagsInTS = differentTags.length; - return doc; - } + declare function patchDocumentField(doc) { + var differentTags = []; + var entries = timeseries(doc, $name).get($from, $to); - from Users as u - update - { - put(id(u), foo(u)) - }", + for (var i = 0; i < entries.length; i++) { + var e = entries[i]; + + if (e.Tag !== null) { + if (!differentTags.includes(e.Tag)) { + differentTags.push(e.Tag); + } + } + } + + doc.NumberOfUniqueTagsInTS = differentTags.length; + return doc; + } + + from Users as u + update { + put(id(u), patchDocumentField(u)) + }", QueryParameters = new Parameters { - { "name", "ExerciseHeartRate" }, + { "name", "HeartRates" }, { "from", DateTime.MinValue }, { "to", DateTime.MaxValue } } }); - var result = store.Operations.Send(patchNumOfUniqueTags).WaitForCompletion(); + // Execute the operation and Wait for completion: + var result = store.Operations.Send(patchNumberOfUniqueTags).WaitForCompletion(); #endregion // Delete time-series from all users @@ -2450,8 +2464,8 @@ from Users as u { "to", DateTime.MaxValue } } }); + store.Operations.Send(removeOperation); - } } @@ -2973,13 +2987,13 @@ public PatchCommandData(string id, string changeVector, } #region PatchRequest-definition - private class PatchRequest + public class PatchRequest { - // Patching script + // The patching script public string Script { get; set; } - // Values that can be used by the patching script + + // Values for the parameters used by the patching script public Dictionary Values { get; set; } - //... } #endregion @@ -3061,8 +3075,11 @@ public class TimeSeriesDetails private class PatchOperation { #region PatchOperation-Definition - public PatchOperation(string id, string changeVector, - PatchRequest patch, PatchRequest patchIfMissing = null, + public PatchOperation( + string id, + string changeVector, + PatchRequest patch, + PatchRequest patchIfMissing = null, bool skipPatchIfChangeVectorMismatch = false) #endregion { } @@ -3070,10 +3087,14 @@ public PatchOperation(string id, string changeVector, private class PatchByQueryOperation { - #region PatchByQueryOperation-Definition - public PatchByQueryOperation(IndexQuery queryToUpdate, - QueryOperationOptions options = null) - #endregion + #region PatchByQueryOperation-Definition-1 + public PatchByQueryOperation(string queryToUpdate) + #endregion + { } + + #region PatchByQueryOperation-Definition-2 + public PatchByQueryOperation(IndexQuery queryToUpdate, QueryOperationOptions options = null) + #endregion { } } diff --git a/Documentation/5.4/Samples/nodejs/documentExtensions/timeSeries/client-api/patchOperations.js b/Documentation/5.4/Samples/nodejs/documentExtensions/timeSeries/client-api/patchOperations.js new file mode 100644 index 0000000000..d7ba50cf68 --- /dev/null +++ b/Documentation/5.4/Samples/nodejs/documentExtensions/timeSeries/client-api/patchOperations.js @@ -0,0 +1,184 @@ +import { DocumentStore } from "ravendb"; + +const documentStore = new DocumentStore(); + +async function patchOperations() { + { + //region patch_1 + const baseTime = new Date(); + + const patchRequest = new PatchRequest(); + + // Define the patch request using JavaScript: + patchRequest.script = "timeseries(this, $timeseries).append($timestamp, $values, $tag);"; + + // Provide values for the parameters in the script: + patchRequest.values = { + timeseries: "HeartRates", + timestamp: baseTime.toISOString(), + values: 59, + tag: "watches/fitbit" + }; + + // Define the patch operation: + const patchOp = new PatchOperation("users/john", null, patchRequest); + + // Execute the operation: + await documentStore.operations.send(patchOp); + //endregion + } + { + //region patch_2 + const baseTime = new Date(); + + // Create arrays of timestamps and random values to patch + const values = []; + const timeStamps = []; + + for (let i = 0; i < 100; i++) { + const randomValue = 68 + Math.round(19 * Math.random()); + values.push(randomValue); + + const timeStamp = baseTime.getTime() + 60_000 * i; + timeStamps.push(new Date(timeStamp).toISOString()); + } + + const patchRequest = new PatchRequest(); + + patchRequest.script = ` + for (let i = 0; i < $values.length; i++) { + timeseries(id(this), $timeseries).append( + $timeStamps[i], + $values[i], + $tag); + }`; + + patchRequest.values = { + timeseries: "HeartRates", + timeStamps: timeStamps, + values: values, + tag: "watches/fitbit" + }; + + const patchOp = new PatchOperation("users/john", null, patchRequest); + await documentStore.operations.send(patchOp); + //endregion + } + { + //region patch_3 + const baseTime = new Date(); + + const patchRequest = new PatchRequest(); + + patchRequest.script = "timeseries(this, $timeseries).delete($from, $to);"; + + patchRequest.values = { + timeseries: "HeartRates", + from: baseTime.toISOString(), + to: new Date(baseTime.getTime() + 60_000 * 49).toISOString() + }; + + const patchOp = new PatchOperation("users/john", null, patchRequest); + await documentStore.operations.send(patchOp); + //endregion + } + { + //region patch_4 + const indexQuery = new IndexQuery(); + + // Define the query & patch string: + indexQuery.query = ` + from users as u + update { + timeseries(u, $name).append($time, $values, $tag) + }`; + + // Provide values for the parameters in the script: + indexQuery.queryParameters = { + name: "HeartRates", + time: new Date(baseTime.getTime() + 60_000).toISOString(), + values: 59, + tag: "watches/fitbit" + } + + // Define the patch operation: + const patchByQueryOp = new PatchByQueryOperation(indexQuery); + + // Execute the operation: + await documentStore.operations.send(patchByQueryOp); + //endregion + } + { + //region patch_5 + const indexQuery = new IndexQuery(); + + indexQuery.query = ` + from users as u + where u.age < 30 + update + { + timeseries(u, "HeartRates").delete() + }`; + + const deleteByQueryOp = new PatchByQueryOperation(indexQuery); + + // Execute the operation: + // Time series "HeartRates" will be deleted for all users with age < 30 + await documentStore.operations.send(deleteByQueryOp); + //endregion + } + { + //region patch_6 + const indexQuery = new IndexQuery(); + + indexQuery.query = ` + declare function patchDocumentField(doc) { + var differentTags = []; + var entries = timeseries(doc, $name).get(); + + for (var i = 0; i < entries.length; i++) { + var e = entries[i]; + + if (e.Tag !== null) { + if (!differentTags.includes(e.Tag)) { + differentTags.push(e.Tag); + } + } + } + + doc.numberOfUniqueTagsInTS = differentTags.length; + return doc; + } + + from users as u + update { + put(id(u), patchDocumentField(u)) + } + `; + + indexQuery.queryParameters = { + name: "HeartRates" + } + + const patchByQueryOp = new PatchByQueryOperation(indexQuery); + + // Execute the operation and wait for completion: + const asyncOp = await documentStore.operations.send(patchByQueryOp); + await asyncOp.waitForCompletion(); + //endregion + } +} + +//region user_class +class User { + constructor( + name = '', + age = 0 + ) { + Object.assign(this, { + name, + age + }); + } +} +//endregion diff --git a/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs b/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs index f768718e5d..774ab2b1bc 100644 --- a/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs +++ b/Documentation/6.0/Samples/csharp/Raven.Documentation.Samples/DocumentExtensions/TimeSeries/TimeSeriesTests.cs @@ -1167,12 +1167,10 @@ public void PatchSingleEntryUsingSessionDefer() } }, null)); session.SaveChanges(); - } } } - // patching a document a single time-series entry // using PatchOperation [Fact] @@ -1192,25 +1190,32 @@ public void PatchSingleEntryUsingPatchOperation() } #region TS_region-Operation_Patch-Append-Single-TS-Entry - var baseline = DateTime.Today; - - store.Operations.Send(new PatchOperation("users/1-A", null, - new PatchRequest + var baseTime = DateTime.UtcNow; + + var patchRequest = new PatchRequest + { + // Define the patch request using JavaScript: + Script = "timeseries(this, $timeseries).append($timestamp, $values, $tag);", + + // Provide values for the parameters in the script: + Values = { - Script = "timeseries(this, $timeseries).append($timestamp, $values, $tag);", - Values = - { - { "timeseries", "HeartRates" }, - { "timestamp", baseline.AddMinutes(1) }, - { "values", 59d }, - { "tag", "watches/fitbit" } - } - })); + { "timeseries", "HeartRates" }, + { "timestamp", baseTime.AddMinutes(1) }, + { "values", 59d }, + { "tag", "watches/fitbit" } + } + }; + + // Define the patch operation; + var patchOp = new PatchOperation("users/john", null, patchRequest); + + // Execute the operation: + store.Operations.Send(patchOp); #endregion } } - // Patching: Append and Remove multiple time-series entries // Using session.Advanced.Defer [Fact] @@ -1377,60 +1382,57 @@ public void PatcAndhDeleteMultipleEntriesOperation() using (var session = store.OpenSession()) { #region TS_region-Operation_Patch-Append-100-TS-Entries - var baseline = DateTime.Today; + var baseTime = DateTime.UtcNow; // Create arrays of timestamps and random values to patch - List values = new List(); - List timeStamps = new List(); + var values = new List(); + var timeStamps = new List(); - for (var cnt = 0; cnt < 100; cnt++) + for (var i = 0; i < 100; i++) { values.Add(68 + Math.Round(19 * new Random().NextDouble())); - timeStamps.Add(baseline.AddSeconds(cnt)); + timeStamps.Add(baseTime.AddMinutes(i)); } - store.Operations.Send(new PatchOperation("users/1-A", null, - new PatchRequest + var patchRequest = new PatchRequest + { + Script = @"var i = 0; + for (i = 0; i < $values.length; i++) { + timeseries(id(this), $timeseries).append ( + $timeStamps[i], + $values[i], + $tag); + }", + Values = { - Script = @"var i = 0; - for (i = 0; i < $values.length; i++) - {timeseries(id(this), $timeseries) - .append ( - new Date($timeStamps[i]), - $values[i], - $tag); - }", - Values = - { - { "timeseries", "HeartRates" }, - { "timeStamps", timeStamps}, - { "values", values }, - { "tag", "watches/fitbit" } - } + { "timeseries", "HeartRates" }, + { "timeStamps", timeStamps }, + { "values", values }, + { "tag", "watches/fitbit" } + } + }; - })); + var patchOp = new PatchOperation("users/john", null, patchRequest); + store.Operations.Send(patchOp); #endregion #region TS_region-Operation_Patch-Delete-50-TS-Entries - store.Operations.Send(new PatchOperation("users/1-A", null, + store.Operations.Send(new PatchOperation("users/john", null, new PatchRequest { Script = "timeseries(this, $timeseries).delete($from, $to);", Values = { { "timeseries", "HeartRates" }, - { "from", baseline.AddSeconds(0) }, - { "to", baseline.AddSeconds(49) } + { "from", baseTime }, + { "to", baseTime.AddMinutes(49) } } })); #endregion - } } } - - //Query Time-Series Using Raw RQL [Fact] public void QueryTimeSeriesUsingRawRQL() @@ -2221,21 +2223,30 @@ public async Task PatchTimeSerieshByQuery() var baseline = DateTime.Today; #region TS_region-PatchByQueryOperation-Append-To-Multiple-Docs - PatchByQueryOperation appendRestHeartRateOperation = new PatchByQueryOperation(new IndexQuery + var indexQuery = new IndexQuery { - Query = @"from Users as u update - { - timeseries(u, $name).append($time, $values, $tag) - }", + // Define the query and the patching action that follows the 'update' keyword: + Query = @"from Users as u + update + { + timeseries(u, $name).append($time, $values, $tag) + }", + + // Provide values for the parameters in the script: QueryParameters = new Parameters - { - { "name", "RestHeartRate" }, - { "time", baseline.AddMinutes(1) }, - { "values", new[]{59d} }, - { "tag", "watches/fitbit1" } - } - }); - store.Operations.Send(appendRestHeartRateOperation); + { + { "name", "HeartRates" }, + { "time", baseline.AddMinutes(1) }, + { "values", new[] {59d} }, + { "tag", "watches/fitbit" } + } + }; + + // Define the patch operation: + var patchByQueryOp = new PatchByQueryOperation(indexQuery); + + // Execute the operation: + store.Operations.Send(patchByQueryOp); #endregion // Append time series to multiple documents @@ -2311,23 +2322,26 @@ from Users as u var result = store.Operations.Send(getExerciseHeartRateOperation).WaitForCompletion(); #region TS_region-PatchByQueryOperation-Delete-From-Multiple-Docs - PatchByQueryOperation deleteOperation = new PatchByQueryOperation(new IndexQuery + PatchByQueryOperation deleteByQueryOp = new PatchByQueryOperation(new IndexQuery { Query = @"from Users as u - where u.age < 30 + where u.Age < 30 update { timeseries(u, $name).delete($from, $to) }", + QueryParameters = new Parameters - { - { "name", "HeartRates" }, - { "from", DateTime.MinValue }, - { "to", DateTime.MaxValue } - } + { + { "name", "HeartRates" }, + { "from", DateTime.MinValue }, + { "to", DateTime.MaxValue } + } }); - store.Operations.Send(deleteOperation); + // Execute the operation: + // Time series "HeartRates" will be deleted for all users with age < 30 + store.Operations.Send(deleteByQueryOp); #endregion } } @@ -2403,38 +2417,38 @@ public async Task PatchTimeSerieshByQueryWithGet() PatchByQueryOperation patchNumOfUniqueTags = new PatchByQueryOperation(new IndexQuery { Query = @" - declare function foo(doc){ - var entries = timeseries(doc, $name).get($from, $to); - var differentTags = []; - for (var i = 0; i < entries.length; i++) - { - var e = entries[i]; - if (e.Tag !== null) - { - if (!differentTags.includes(e.Tag)) - { - differentTags.push(e.Tag); - } - } - } - doc.NumberOfUniqueTagsInTS = differentTags.length; - return doc; - } + declare function patchDocumentField(doc) { + var differentTags = []; + var entries = timeseries(doc, $name).get($from, $to); - from Users as u - update - { - put(id(u), foo(u)) - }", + for (var i = 0; i < entries.length; i++) { + var e = entries[i]; + + if (e.Tag !== null) { + if (!differentTags.includes(e.Tag)) { + differentTags.push(e.Tag); + } + } + } + + doc.NumberOfUniqueTagsInTS = differentTags.length; + return doc; + } + + from Users as u + update { + put(id(u), patchDocumentField(u)) + }", QueryParameters = new Parameters { - { "name", "ExerciseHeartRate" }, + { "name", "HeartRates" }, { "from", DateTime.MinValue }, { "to", DateTime.MaxValue } } }); + // Execute the operation and Wait for completion: var result = store.Operations.Send(patchNumOfUniqueTags).WaitForCompletion(); #endregion @@ -2453,8 +2467,8 @@ from Users as u { "to", DateTime.MaxValue } } }); + store.Operations.Send(removeOperation); - } } @@ -2976,13 +2990,13 @@ public PatchCommandData(string id, string changeVector, } #region PatchRequest-definition - private class PatchRequest + public class PatchRequest { - // Patching script + // The patching script public string Script { get; set; } - // Values that can be used by the patching script + + // Values for the parameters used by the patching script public Dictionary Values { get; set; } - //... } #endregion @@ -3064,8 +3078,11 @@ public class TimeSeriesDetails private class PatchOperation { #region PatchOperation-Definition - public PatchOperation(string id, string changeVector, - PatchRequest patch, PatchRequest patchIfMissing = null, + public PatchOperation( + string id, + string changeVector, + PatchRequest patch, + PatchRequest patchIfMissing = null, bool skipPatchIfChangeVectorMismatch = false) #endregion { } @@ -3073,10 +3090,14 @@ public PatchOperation(string id, string changeVector, private class PatchByQueryOperation { - #region PatchByQueryOperation-Definition - public PatchByQueryOperation(IndexQuery queryToUpdate, - QueryOperationOptions options = null) - #endregion + #region PatchByQueryOperation-Definition-1 + public PatchByQueryOperation(string queryToUpdate) + #endregion + { } + + #region PatchByQueryOperation-Definition-2 + public PatchByQueryOperation(IndexQuery queryToUpdate, QueryOperationOptions options = null) + #endregion { } }