diff --git a/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/bulk-insert/append-in-bulk.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/bulk-insert/append-in-bulk.dotnet.markdown new file mode 100644 index 0000000000..55be08b74c --- /dev/null +++ b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/bulk-insert/append-in-bulk.dotnet.markdown @@ -0,0 +1,127 @@ +# Append Time Series with Bulk Insert + +--- + +{NOTE: } + +* `store.BulkInsert` is RavenDB's high-performance data insertion operation. + +* The `bulkInsert.TimeSeriesFor` interface provides similar functionality to the [session.TimeSeriesFor](../../../../document-extensions/timeseries/client-api/session/append), + but without the overhead associated with the _Session_, resulting in significantly improved performance. + +* In this page: + * [Usage](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#usage) + * [Examples](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#examples) + * [Append single entry](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-single-entry) + * [Append multiple entries](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-entries) + * [Append multiple values per entry](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-values-per-entry) + * [Append multiple time series](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-time-series) + * [Syntax](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#syntax) + +{NOTE/} + +{PANEL: Usage} + +**Flow**: + +* Call `store.BulkInsert` to create a `BulkInsertOperation` instance. +* Call `TimeSeriesFor` on that instance and pass it: + * The document ID + (An exception will be thrown if the specified document does Not exist). + * The time series name + (Appending entries to a time series that doesn't yet exist yet will create the time series). +* To append an entry, call `Append` and pass it: + * The entry's Timestamp + * The entry's Value or Values + * The entry's Tag (optional) + +**Note**: + +* To append multiple entries, call `Append` as many times as needed. +* Ensure there is at least a 1-millisecond interval between each timestamp. +* The client converts all timestamps to **UTC** before sending the batch to the server. +* Multiple time series can be appended in the same `BulkInsertOperation`. See this [example](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-time-series) below. + +{PANEL/} + +{PANEL: Examples} + +{NOTE: } + __Append single entry__: + +--- +In this example, we append a single entry with a single value to time series "HeartRates". +{CODE timeseries_region_Use-BulkInsert-To-Append-single-entry@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + __Append multiple entries__: + +--- +In this example, we append 100 entries with a single value to time series "HeartRates". +{CODE timeseries_region_Use-BulkInsert-To-Append-100-Entries@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + __Append multiple values per entry__: + +--- +In this example, we append multiple values per entry in time series "HeartRates". +{CODE BulkInsert-overload-2-Two-HeartRate-Sets@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{NOTE: } + __Append multiple time series__: + +--- +In this example, we append multiple time series in different documents in the same batch. +{CODE timeseries_region_Use-BulkInsert-To-Append-multiple-timeseries@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +{NOTE/} + +{PANEL/} + +{PANEL: Syntax} + +**`BulkInsert.TimeSeriesFor`** + +{CODE-BLOCK: JSON} +public TimeSeriesBulkInsert TimeSeriesFor(string id, string name) +{CODE-BLOCK/} + +| Parameter | Type | Description | +|-------------|----------|------------------| +| **id** | `string` | Document ID | +| **name** | `string` | Time Series Name | + +**`TimeSeriesFor.Append`** overloads: + +{CODE Append-Operation-Definition-1@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} +{CODE Append-Operation-Definition-2@DocumentExtensions\TimeSeries\TimeSeriesTests.cs /} + +| Parameter | Type | Description | +|---------------|-----------------------|---------------------------| +| **timestamp** | `DateTime` | TS-entry's timestamp | +| **value** | `double` | A single value | +| **values** | `ICollection` | Multiple values | +| **tag** | `string` | TS-entry's tag (optional) | + +{PANEL/} + +## Related articles + +**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/bulk-insert/append-in-bulk.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/bulk-insert/append-in-bulk.js.markdown new file mode 100644 index 0000000000..76de3d8c13 --- /dev/null +++ b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/bulk-insert/append-in-bulk.js.markdown @@ -0,0 +1,124 @@ +# Append Time Series with Bulk Insert + +--- + +{NOTE: } + +* `bulkInsert` is RavenDB's high-performance data insertion operation. + +* The `bulkInsert.timeSeriesFor` interface provides similar functionality to the [session.timeSeriesFor](../../../../document-extensions/timeseries/client-api/session/append), + but without the overhead associated with the _Session_, resulting in significantly improved performance. + +* In this page: + * [Usage](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#usage) + * [Examples](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#examples) + * [Append single entry](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-single-entry) + * [Append multiple entries](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-entries) + * [Append multiple values per entry](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-values-per-entry) + * [Append multiple time series](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-time-series) + * [Syntax](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#syntax) + +{NOTE/} + +{PANEL: Usage} + +**Flow**: + +* Call `documentStore.bulkInsert` to create a `BulkInsertOperation` instance. +* Call `timeSeriesFor` on that instance and pass it: + * The document ID + (An exception will be thrown if the specified document does Not exist). + * The time series name + (Appending entries to a time series that doesn't yet exist yet will create the time series). +* To append an entry, call `append` and pass it: + * The entry's Timestamp + * The entry's Value or Values + * The entry's Tag (optional) + +**Note**: + +* To append multiple entries, call `append` as many times as needed. +* Ensure there is at least a 1-millisecond interval between each timestamp. +* The client converts all timestamps to **UTC** before sending the batch to the server. +* Multiple time series can be appended in the same `BulkInsertOperation`. See this [example](../../../../document-extensions/timeseries/client-api/bulk-insert/append-in-bulk#append-multiple-time-series) below. + +{PANEL/} + +{PANEL: Examples} + +{NOTE: } + __Append single entry__: + +--- +In this example, we append a single entry with a single value to time series "HeartRates". +{CODE:nodejs append_1@documentExtensions\timeSeries\client-api\appendWithBulkInsert.js /} + +{NOTE/} + +{NOTE: } + __Append multiple entries__: + +--- +In this example, we append 100 entries with a single value to time series "HeartRates". +{CODE:nodejs append_2@documentExtensions\timeSeries\client-api\appendWithBulkInsert.js /} + +{NOTE/} + +{NOTE: } + __Append multiple values per entry__: + +--- +In this example, we append multiple values per entry in time series "HeartRates". +{CODE:nodejs append_3@documentExtensions\timeSeries\client-api\appendWithBulkInsert.js /} + +{NOTE/} + +{NOTE: } + __Append multiple time series__: + +--- +In this example, we append multiple time series in different documents in the same batch. +{CODE:nodejs append_4@documentExtensions\timeSeries\client-api\appendWithBulkInsert.js /} + +{NOTE/} + +{PANEL/} + +{PANEL: Syntax} + +**`bulkInsert.timeSeriesFor`** + +{CODE:nodejs syntax_1@documentExtensions\timeSeries\client-api\appendWithBulkInsert.js /} + +| Parameter | Type | Description | +|-------------|----------|------------------| +| **id** | `string` | Document ID | +| **name** | `string` | Time Series Name | + +**`timeSeriesFor.Append`** overloads: + +{CODE:nodejs syntax_2@documentExtensions\timeSeries\client-api\appendWithBulkInsert.js /} + +| Parameter | Type | Description | +|---------------|------------|---------------------------| +| **timestamp** | `Date` | TS-entry's timestamp | +| **value** | `number` | A single value | +| **values** | `number[]` | Multiple values | +| **tag** | `string` | TS-entry's tag (optional) | + +{PANEL/} + +## Related articles + +**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/append-and-delete.dotnet.markdown b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.dotnet.markdown index d880157e0d..4f04e4f97b 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.dotnet.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.dotnet.markdown @@ -24,21 +24,25 @@ {PANEL: Usage} +**Flow**: + * Prepare the Append and Delete operations: * Create an instance of `TimeSeriesOperation.AppendOperation` to define an Append action. * Create an instance of ` TimeSeriesOperation.DeleteOperation` fo define a Delete action. - * Create an instance of `TimeSeriesOperation` and pass it the the time series name. * Call `TimeSeriesOperation.Append` to add the Append operation. * Call `TimeSeriesOperation.Delete` to add the Delete operation. - * Create a `TimeSeriesBatchOperation` instance and pass it: * The document ID * The `TimeSeriesOperation` object - * Execute the `TimeSeriesBatchOperation` operation by calling `store.Operations.Send` - * All the added Append and Delete operations will be executed in a single-node transaction. - * Delete actions are executed **before** Append actions. As seen in [this example](../../../../document-extensions/timeseries/client-api/operations/append-and-delete#append--delete-entries-in-the-same-batch). + +**Note**: + +* All the added Append and Delete operations will be executed in a single-node transaction. +* Delete actions are executed **before** Append actions. As seen in [this example](../../../../document-extensions/timeseries/client-api/operations/append-and-delete#append--delete-entries-in-the-same-batch). +* Appending entries to a time series that doesn't yet exist yet will create the time series. +* An exception will be thrown if the specified document does Not exist. {PANEL/} diff --git a/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.js.markdown b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.js.markdown index 4482c6af46..4a3b1f5fdf 100644 --- a/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.js.markdown +++ b/Documentation/5.4/Raven.Documentation.Pages/document-extensions/timeseries/client-api/operations/append-and-delete.js.markdown @@ -24,21 +24,25 @@ {PANEL: Usage} +**Flow**: + * Prepare the Append and Delete operations: * Create an instance of `TimeSeriesOperation.AppendOperation` to define an Append action. * Create an instance of ` TimeSeriesOperation.DeleteOperation` fo define a Delete action. - * Create an instance of `TimeSeriesOperation` and pass it the the time series name. * Call `TimeSeriesOperation.append` to add the Append operation. * Call `TimeSeriesOperation.delete` to add the Delete operation. - * Create a `TimeSeriesBatchOperation` instance and pass it: * The document ID * The `TimeSeriesOperation` object - * Execute the `TimeSeriesBatchOperation` operation by calling `store.operations.send` + +**Note**: + * All the added Append and Delete operations will be executed in a single-node transaction. * Delete actions are executed **before** Append actions. As seen in [this example](../../../../document-extensions/timeseries/client-api/operations/append-and-delete#append--delete-entries-in-the-same-batch). + * Appending entries to a time series that doesn't yet exist yet will create the time series. + * An exception will be thrown if the specified document does Not exist. {PANEL/} 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 aeb50fc2da..1c03b9162c 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 @@ -928,50 +928,83 @@ public void AppendUsingBulkInsert() // Create a document using (var session = store.OpenSession()) { - var user = new User - { - Name = "John" - }; - session.Store(user); + var user1 = new User { Name = "John" }; + session.Store(user1, "users/john"); + + var user2 = new User { Name = "Jane" }; + session.Store(user2, "users/jane"); session.SaveChanges(); } - - // Query for a document with the Name property "John" and append it a time point + using (var session = store.OpenSession()) { - var baseline = DateTime.Today; - - IRavenQueryable query = session.Query() - .Where(u => u.Name == "John"); - - var result = query.ToList(); - string documentId = result[0].Id; - - #region timeseries_region_Use-BulkInsert-To-Append-2-Entries - // Use BulkInsert to append 2 time-series entries + #region timeseries_region_Use-BulkInsert-To-Append-single-entry + var baseTime = DateTime.Today; + + // Create a BulkInsertOperation instance using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + // Create a TimeSeriesBulkInsert instance + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + // Call 'TimeSeriesFor', pass it: + // * The document ID + // * The time series name + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(2), 61d, "watches/fitbit"); - timeSeriesBulkInsert.Append(baseline.AddMinutes(3), 62d, "watches/apple-watch"); + // Call 'Append' to add an entry, pass it: + // * The entry's Timestamp + // * The entry's Value or Values + // * The entry's Tag (optional) + timeSeriesBulkInsert.Append(baseTime.AddMinutes(1), 61d, "watches/fitbit"); } } #endregion #region timeseries_region_Use-BulkInsert-To-Append-100-Entries - // Use BulkInsert to append 100 time-series entries using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - for (int minute = 0; minute < 100; minute++) + Random rand = new Random(); + + for (int i = 0; i < 100; i++) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(minute), new double[] { 80d }, "watches/fitbit"); + double randomValue = rand.Next(60, 91); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(i), randomValue, "watches/fitbit"); } } } #endregion + + #region timeseries_region_Use-BulkInsert-To-Append-multiple-timeseries + using (BulkInsertOperation bulkInsert = store.BulkInsert()) + { + // Append first time series + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) + { + timeSeriesBulkInsert.Append(baseTime.AddMinutes(1), 61d, "watches/fitbit"); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(2), 62d, "watches/fitbit"); + } + + // Append another time series + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "ExerciseHeartRates")) + { + timeSeriesBulkInsert.Append(baseTime.AddMinutes(3), 81d, "watches/apple-watch"); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(4), 82d, "watches/apple-watch"); + } + + // Append time series in another document + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/jane", "HeartRates")) + { + timeSeriesBulkInsert.Append(baseTime.AddMinutes(1), 59d, "watches/fitbit"); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(2), 60d, "watches/fitbit"); + } + } + #endregion } } } @@ -990,63 +1023,46 @@ public void AppendUsingBulkInsertIEnumerable() { Name = "John" }; - session.Store(user); + session.Store(user, "users/john"); session.SaveChanges(); } - - // Query for a document with the Name property "John" and append it a time point + using (var session = store.OpenSession()) { var baseline = DateTime.Today; - IRavenQueryable query = session.Query() - .Where(u => u.Name == "John"); - - var result = query.ToList(); - string documentId = result[0].Id; - #region BulkInsert-overload-2-Two-HeartRate-Sets - // Use BulkInsert to append 2 sets of time series entries using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - - ICollection ExerciseHeartRate = new List - { 89d, 82d, 85d }; - - ICollection RestingHeartRate = new List - {59d, 63d, 61d, 64d, 64d, 65d }; - - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(2), ExerciseHeartRate, "watches/fitbit"); - timeSeriesBulkInsert.Append(baseline.AddMinutes(3), RestingHeartRate, "watches/apple-watch"); + var exerciseHeartRates = new List { 89d, 82d, 85d }; + timeSeriesBulkInsert.Append(baseline.AddMinutes(1), exerciseHeartRates, "watches/fitbit"); + + var restingHeartRates = new List { 59d, 63d, 61d, 64d, 65d }; + timeSeriesBulkInsert.Append(baseline.AddMinutes(2), restingHeartRates, "watches/apple-watch"); } } #endregion - ICollection values = new List - {59d, 63d, 71d, 69d, 64, 65d }; + ICollection values = new List { 59d, 63d, 71d, 69d, 64d, 65d }; // Use BulkInsert to append 100 multi-values time-series entries using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - for (int minute = 0; minute < 100; minute++) + for (int i = 0; i < 100; i++) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(minute), values, "watches/fitbit"); + timeSeriesBulkInsert.Append(baseline.AddMinutes(i), values, "watches/fitbit"); } } } - } } } - - - - // patching [Fact] public void PatchTimeSeries() @@ -3034,15 +3050,14 @@ public PatchByQueryOperation(IndexQuery queryToUpdate, private class TimeSeriesBulkInsert { #region Append-Operation-Definition-1 - // Each appended entry has a single value. + // Append a single value public void Append(DateTime timestamp, double value, string tag = null) #endregion { } #region Append-Operation-Definition-2 - // Each appended entry has multiple values. - public void Append(DateTime timestamp, - ICollection values, string tag = null) + // Append multiple values + public void Append(DateTime timestamp, ICollection values, string tag = null) #endregion { } } diff --git a/Documentation/5.4/Samples/nodejs/documentExtensions/timeSeries/client-api/appendWithBulkInsert.js b/Documentation/5.4/Samples/nodejs/documentExtensions/timeSeries/client-api/appendWithBulkInsert.js new file mode 100644 index 0000000000..98916e8537 --- /dev/null +++ b/Documentation/5.4/Samples/nodejs/documentExtensions/timeSeries/client-api/appendWithBulkInsert.js @@ -0,0 +1,122 @@ +import { DocumentStore } from "ravendb"; + +const documentStore = new DocumentStore(); + +async function appendWithBulkInsert() { + { + //region append_1 + const baseTime = new Date(); + + // Create a BulkInsertOperation instance + const bulkInsert = documentStore.bulkInsert(); + + { + // Call 'TimeSeriesFor', pass it: + // * The document ID + // * The time series name + const timeSeriesBulkInsert = bulkInsert.timeSeriesFor("users/john", "HeartRates"); + + // Call 'Append' to add an entry, pass it: + // * The entry's Timestamp + // * The entry's Value or Values + // * The entry's Tag (optional) + const nextMinute = new Date(baseTime.getTime() + 60_000 * 1); + await timeSeriesBulkInsert.append(nextMinute, 61, "watches/fitbit"); + + timeSeriesBulkInsert.dispose(); + } + + // Call finish to send all data to the server + await bulkInsert.finish(); + //endregion + } + { + //region append_2 + const baseTime = new Date(); + + const bulkInsert = documentStore.bulkInsert(); + + { + const timeSeriesBulkInsert = bulkInsert.timeSeriesFor("users/john", "HeartRates"); + + for (let i = 0; i < 100; i++) { + let randomValue = Math.floor(Math.random() * (29)) + 60; + let nextMinute = new Date(baseTime.getTime() + 60_000 * (i + 1)); + + await timeSeriesBulkInsert.append(nextMinute, randomValue, "watches/fitbit"); + } + + timeSeriesBulkInsert.dispose(); + } + + await bulkInsert.finish(); + //endregion + } + { + //region append_3 + const baseTime = new Date(); + + const bulkInsert = documentStore.bulkInsert(); + + { + const timeSeriesBulkInsert = bulkInsert.timeSeriesFor("users/john", "HeartRates"); + + const exerciseHeartRates = [89, 82, 85]; + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000), + exerciseHeartRates, "watches/fitbit"); + + const restingHeartRates = [59, 63, 61, 64, 65]; + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000 * 2), + restingHeartRates, "watches/fitbit"); + + timeSeriesBulkInsert.dispose(); + } + + await bulkInsert.finish(); + //endregion + } + { + //region append_4 + const baseTime = new Date(); + + const bulkInsert = documentStore.bulkInsert(); + + { + // Append first time series + const timeSeriesBulkInsert = bulkInsert.timeSeriesFor("users/john", "HeartRates"); + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000), 61, "watches/fitbit"); + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000 * 2), 62, "watches/fitbit"); + timeSeriesBulkInsert.dispose(); + } + { + // Append another time series + const timeSeriesBulkInsert = bulkInsert.timeSeriesFor("users/john", "ExerciseHeartRates"); + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000 * 3), 81, "watches/apple-watch"); + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000 * 4), 82, "watches/apple-watch"); + timeSeriesBulkInsert.dispose(); + } + { + // Append time series in another document + const timeSeriesBulkInsert = bulkInsert.timeSeriesFor("users/jane", "HeartRates"); + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000), 59, "watches/fitbit"); + await timeSeriesBulkInsert.append(new Date(baseTime.getTime() + 60_000 * 2), 60, "watches/fitbit"); + timeSeriesBulkInsert.dispose(); + } + + await bulkInsert.finish(); + //endregion + } +} + +//region syntax_1 +timeSeriesFor(id, name); +//endregion + +//region syntax_2 +append(timestamp, value); +append(timestamp, value, tag); +append(timestamp, values); +append(timestamp, values, tag); +//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 8ecfcf445e..f984baa182 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 @@ -929,50 +929,83 @@ public void AppendUsingBulkInsert() // Create a document using (var session = store.OpenSession()) { - var user = new User - { - Name = "John" - }; - session.Store(user); + var user1 = new User { Name = "John" }; + session.Store(user1, "users/john"); + + var user2 = new User { Name = "Jane" }; + session.Store(user2, "users/jane"); session.SaveChanges(); } - - // Query for a document with the Name property "John" and append it a time point + using (var session = store.OpenSession()) { - var baseline = DateTime.Today; - - IRavenQueryable query = session.Query() - .Where(u => u.Name == "John"); - - var result = query.ToList(); - string documentId = result[0].Id; - - #region timeseries_region_Use-BulkInsert-To-Append-2-Entries - // Use BulkInsert to append 2 time-series entries + #region timeseries_region_Use-BulkInsert-To-Append-single-entry + var baseTime = DateTime.Today; + + // Create a BulkInsertOperation instance using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + // Create a TimeSeriesBulkInsert instance + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + // Call 'TimeSeriesFor', pass it: + // * The document ID + // * The time series name + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(2), 61d, "watches/fitbit"); - timeSeriesBulkInsert.Append(baseline.AddMinutes(3), 62d, "watches/apple-watch"); + // Call 'Append' to add an entry, pass it: + // * The entry's Timestamp + // * The entry's Value or Values + // * The entry's Tag (optional) + timeSeriesBulkInsert.Append(baseTime.AddMinutes(1), 61d, "watches/fitbit"); } } #endregion #region timeseries_region_Use-BulkInsert-To-Append-100-Entries - // Use BulkInsert to append 100 time-series entries using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - for (int minute = 0; minute < 100; minute++) + Random rand = new Random(); + + for (int i = 0; i < 100; i++) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(minute), new double[] { 80d }, "watches/fitbit"); + double randomValue = rand.Next(60, 91); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(i), randomValue, "watches/fitbit"); } } } #endregion + + #region timeseries_region_Use-BulkInsert-To-Append-multiple-timeseries + using (BulkInsertOperation bulkInsert = store.BulkInsert()) + { + // Append first time series + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) + { + timeSeriesBulkInsert.Append(baseTime.AddMinutes(1), 61d, "watches/fitbit"); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(2), 62d, "watches/fitbit"); + } + + // Append another time series + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "ExerciseHeartRates")) + { + timeSeriesBulkInsert.Append(baseTime.AddMinutes(3), 81d, "watches/apple-watch"); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(4), 82d, "watches/apple-watch"); + } + + // Append time series in another document + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/jane", "HeartRates")) + { + timeSeriesBulkInsert.Append(baseTime.AddMinutes(1), 59d, "watches/fitbit"); + timeSeriesBulkInsert.Append(baseTime.AddMinutes(2), 60d, "watches/fitbit"); + } + } + #endregion } } } @@ -991,63 +1024,46 @@ public void AppendUsingBulkInsertIEnumerable() { Name = "John" }; - session.Store(user); + session.Store(user, "users/john"); session.SaveChanges(); } - - // Query for a document with the Name property "John" and append it a time point + using (var session = store.OpenSession()) { var baseline = DateTime.Today; - IRavenQueryable query = session.Query() - .Where(u => u.Name == "John"); - - var result = query.ToList(); - string documentId = result[0].Id; - #region BulkInsert-overload-2-Two-HeartRate-Sets - // Use BulkInsert to append 2 sets of time series entries using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - - ICollection ExerciseHeartRate = new List - { 89d, 82d, 85d }; - - ICollection RestingHeartRate = new List - {59d, 63d, 61d, 64d, 64d, 65d }; - - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + using (TimeSeriesBulkInsert timeSeriesBulkInsert = + bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(2), ExerciseHeartRate, "watches/fitbit"); - timeSeriesBulkInsert.Append(baseline.AddMinutes(3), RestingHeartRate, "watches/apple-watch"); + var exerciseHeartRates = new List { 89d, 82d, 85d }; + timeSeriesBulkInsert.Append(baseline.AddMinutes(1), exerciseHeartRates, "watches/fitbit"); + + var restingHeartRates = new List { 59d, 63d, 61d, 64d, 65d }; + timeSeriesBulkInsert.Append(baseline.AddMinutes(2), restingHeartRates, "watches/apple-watch"); } } #endregion - ICollection values = new List - {59d, 63d, 71d, 69d, 64, 65d }; + ICollection values = new List { 59d, 63d, 71d, 69d, 64d, 65d }; // Use BulkInsert to append 100 multi-values time-series entries using (BulkInsertOperation bulkInsert = store.BulkInsert()) { - using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor(documentId, "HeartRates")) + using (TimeSeriesBulkInsert timeSeriesBulkInsert = bulkInsert.TimeSeriesFor("users/john", "HeartRates")) { - for (int minute = 0; minute < 100; minute++) + for (int i = 0; i < 100; i++) { - timeSeriesBulkInsert.Append(baseline.AddMinutes(minute), values, "watches/fitbit"); + timeSeriesBulkInsert.Append(baseline.AddMinutes(i), values, "watches/fitbit"); } } } - } } } - - - - // patching [Fact] public void PatchTimeSeries() @@ -3037,16 +3053,15 @@ public PatchByQueryOperation(IndexQuery queryToUpdate, private class TimeSeriesBulkInsert { #region Append-Operation-Definition-1 - // Each appended entry has a single value. + // Append a single value public void Append(DateTime timestamp, double value, string tag = null) - #endregion + #endregion { } #region Append-Operation-Definition-2 - // Each appended entry has multiple values. - public void Append(DateTime timestamp, - ICollection values, string tag = null) - #endregion + // Append multiple values + public void Append(DateTime timestamp, ICollection values, string tag = null) + #endregion { } }