Skip to main content

Operations: Patch Time Series

Patching Operations

  • To patch time series data, use PatchOperation or PatchByQueryOperation.
  • PatchOperation is RavenDB's operation for single-document patching, and PatchByQueryOperation is used for set-based document operations. You can use both to patch time series data, by customizing the JavaScript they are using.
  • Use PatchOperation to load a document by its ID and patch it time series entries.

    Here, for example, we use PatchOperation to patch a document a single time series entry.

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 =
{
{ "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);
  • Use PatchByQueryOperation to run a document query and patch time series entries to matching documents.

    Here, we use PatchByQueryOperation to append a time series entry to all documents of the User collection.

var indexQuery = new IndexQuery
{
// 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", "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);

PatchOperation

Syntax

  • PatchOperation
    • Definition
public PatchOperation(
string id,
string changeVector,
PatchRequest patch,
PatchRequest patchIfMissing = null,
bool skipPatchIfChangeVectorMismatch = false)
  • Parameters

    ParametersTypeDescription
    idstringPatched document ID
    changeVectorstringChange vector, to verify that the document hasn't been modified.
    Can be null.
    patchPatchRequestThe patching JavaScript
    patchIfMissingPatchRequestPatching JavaScript to be used if the document isn't found
    skipPatchIfChangeVectorMismatchboolIf true, do not patch if the document has been modified
    default: false
  • PatchRequest

    • Definition
public class PatchRequest
{
// The patching script
public string Script { get; set; }

// Values for the parameters used by the patching script
public Dictionary<string, object> Values { get; set; }
}
  • Parameters

    ParametersTypeDescription
    ScriptstringPatching script
    ValuesDictionary<string, object>Values that the patching script can use

Usage Flow

  • Create an instance of PatchOperation and pass its constructor -
    • the document ID
    • the change vector (or null)
    • a new PatchRequest instance
  • Use the PatchRequest instance to pass PatchOperation a JavaScript that appends or deletes time series entries.
  • Call store.Operations.Send to execute the operation.

Usage Samples

  • In this sample, we provide PatchOperationwith a script that appends 100 time series entries to a document.
    Timestamps and values are drawn from an array, and other arguments are provided in the "Values" section.
var baseTime = DateTime.UtcNow;

// Create arrays of timestamps and random values to patch
var values = new List<double>();
var timeStamps = new List<DateTime>();

for (var i = 0; i < 100; i++)
{
values.Add(68 + Math.Round(19 * new Random().NextDouble()));
timeStamps.Add(baseTime.AddMinutes(i));
}

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 =
{
{ "timeseries", "HeartRates" },
{ "timeStamps", timeStamps },
{ "values", values },
{ "tag", "watches/fitbit" }
}
};

var patchOp = new PatchOperation("users/john", null, patchRequest);
store.Operations.Send(patchOp);
  • In this sample, we use PatchOperation to delete a range of 50 time series entries from a document.
store.Operations.Send(new PatchOperation("users/john", null,
new PatchRequest
{
Script = "timeseries(this, $timeseries).delete($from, $to);",
Values =
{
{ "timeseries", "HeartRates" },
{ "from", baseTime },
{ "to", baseTime.AddMinutes(49) }
}
}));

PatchByQueryOperation

Syntax

  • store.Operations.Send Definition
public Operation Send(IOperation<OperationIdResult> operation, 
SessionInfo sessionInfo = null)
  • PatchByQueryOperation Definition
-1
public PatchByQueryOperation(string queryToUpdate)
  • Parameters

    ParametersTypeDescription
    queryToUpdateIndexQueryThe query, including the JavaScript
    QueryOperationOptionsoptionsAdditional options
    Default: null
  • Return Value: Operation

Usage Flow

  • Create a PatchByQueryOperation operation.
  • Pass PatchByQueryOperation a new IndexQuery instance.
  • Add the IndexQuery instance a JavaScript that specifies the query you want to run.
  • Call store.Operations.Send to execute the operation.

Usage Samples

  • In this sample, we run a document query and delete the HeartRate time series from documents we find.
PatchByQueryOperation deleteByQueryOp = new PatchByQueryOperation(new IndexQuery
{
Query = @"from Users as u
where u.Age < 30
update
{
timeseries(u, $name).delete($from, $to)
}",

QueryParameters = new Parameters
{
{ "name", "HeartRates" },
{ "from", DateTime.MinValue },
{ "to", DateTime.MaxValue }
}
});

// Execute the operation:
// Time series "HeartRates" will be deleted for all users with age < 30
store.Operations.Send(deleteByQueryOp);
  • In this sample, we patch each User document a "NumberOfUniqueTagsInTS" field with the number of different tags in the user's "ExerciseHeartRate" time series.
    To do this, we use the JavaScript get method to get each time series' entries (the range we choose includes them all), and check each entry's tag.
PatchByQueryOperation patchNumOfUniqueTags = new PatchByQueryOperation(new IndexQuery
{
Query = @"
declare function patchDocumentField(doc) {
var differentTags = [];
var entries = timeseries(doc, $name).get($from, $to);

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", "HeartRates" },
{ "from", DateTime.MinValue },
{ "to", DateTime.MaxValue }
}
});

// Execute the operation and Wait for completion:
var result = store.Operations.Send(patchNumOfUniqueTags).WaitForCompletion();