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 baseline = DateTime.Today;
    
    store.Operations.Send(new PatchOperation("users/1-A", null,
        new PatchRequest
        {
            Script = "timeseries(this, $timeseries).append($timestamp, $values, $tag);",
            Values =
            {
                { "timeseries", "HeartRates" },
                { "timestamp", baseline.AddMinutes(1) },
                { "values", 59d },
                { "tag", "watches/fitbit" }
            }
        }));
  • 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.

    PatchByQueryOperation appendRestHeartRateOperation = new PatchByQueryOperation(new IndexQuery
    {
        Query = @"from Users as u update
                    {
                        timeseries(u, $name).append($time, $values, $tag)
                    }",
        QueryParameters = new Parameters
                {
                    { "name", "RestHeartRate" },
                    { "time", baseline.AddMinutes(1) },
                    { "values", new[]{59d} },
                    { "tag", "watches/fitbit1" }
                }
    });
    store.Operations.Send(appendRestHeartRateOperation);

PatchOperation


Syntax

  • PatchOperation

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

      Parameters Type Description
      id string Patched document ID
      changeVector string Change vector, to verify that the document hasn't been modified.
      Can be null.
      patch PatchRequest The patching JavaScript
      patchIfMissing PatchRequest Patching JavaScript to be used if the document isn't found
      skipPatchIfChangeVectorMismatch bool If true, do not patch if the document has been modified
      default: false
  • PatchRequest

    • Definition

      private class PatchRequest
      {
          // Patching script
          public string Script { get; set; }
          // Values that can be used by the patching script
          public Dictionary<string, object> Values { get; set; }
          //...
      }
    • Parameters

      Parameters Type Description
      Script string Patching script
      Values Dictionary<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 baseline = DateTime.Today;
    
    // Create arrays of timestamps and random values to patch
    List<double> values = new List<double>();
    List<DateTime> timeStamps = new List<DateTime>();
    
    for (var cnt = 0; cnt < 100; cnt++)
    {
        values.Add(68 + Math.Round(19 * new Random().NextDouble()));
        timeStamps.Add(baseline.AddSeconds(cnt));
    }
    
    store.Operations.Send(new PatchOperation("users/1-A", null,
        new PatchRequest
        {
            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" }
            }
    
        }));
  • In this sample, we use PatchOperation to delete a range of 50 time series entries from a document.

    store.Operations.Send(new PatchOperation("users/1-A", null,
        new PatchRequest
        {
            Script = "timeseries(this, $timeseries).delete($from, $to);",
            Values =
            {
                { "timeseries", "HeartRates" },
                { "from", baseline.AddSeconds(0) },
                { "to", baseline.AddSeconds(49) }
            }
        }));

PatchByQueryOperation


Syntax

  • store.Operations.Send Definition

    public Operation Send(IOperation<OperationIdResult> operation, 
                            SessionInfo sessionInfo = null)
  • PatchByQueryOperation Definition

    public PatchByQueryOperation(IndexQuery queryToUpdate, 
        QueryOperationOptions options = null)
    • Parameters

      Parameters Type Description
      queryToUpdate IndexQuery The query, including the JavaScript
      QueryOperationOptions options Additional 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.

    // Delete time-series from all users
    PatchByQueryOperation deleteOperation = new PatchByQueryOperation(new IndexQuery
    {
        Query = @"from Users as u
                    update
                    {
                        timeseries(u, $name).delete($from, $to)
                    }",
        QueryParameters = new Parameters
                {
                    { "name", "HeartRates" },
                    { "from", DateTime.MinValue },
                    { "to", DateTime.MaxValue }
                }
    });
    store.Operations.Send(deleteOperation);
  • 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 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;
      }
    
      from Users as u
      update
      {
       put(id(u), foo(u))
      }",
    
        QueryParameters = new Parameters
        {
            { "name", "ExerciseHeartRate" },
            { "from", DateTime.MinValue },
            { "to", DateTime.MaxValue }
        }
    });
    
    var result = store.Operations.Send(patchNumOfUniqueTags).WaitForCompletion();