Skip to main content

Session: Time Series Querying

Learn more about time series queries in the section dedicated to this subject.

Time Series LINQ Queries

To build a time series LINQ query, start with session.Query and extend it using LINQ expressions.
Here is a simple LINQ query that filters users by their age and retrieves their HeartRate time series, and the RQL equivalent for this query.

// Query - LINQ format
using (var session = store.OpenSession())
{
var baseline = new DateTime(2020, 5, 17, 00, 00, 00);

IRavenQueryable<TimeSeriesRawResult> query =
(IRavenQueryable<TimeSeriesRawResult>)session.Query<User>()
.Where(u => u.Age < 30)
.Select(q => RavenQuery.TimeSeries(q, "HeartRates")
.Where(ts => ts.Tag == "watches/fitbit")
.ToList());

var result = query.ToList();
}

Syntax

session.Query Definition:

IRavenQueryable<T> Query<T>(string indexName = null,
string collectionName = null, bool isMapReduce = false);

Learn more about session.Query here.

Return Value:

  • IRavenQueryable<TimeSeriesAggregationResult> for aggregated data.
    When the query aggregates time series entries, the results are returned in an aggregated array.
  • IRavenQueryable<TimeSeriesRawResult> for non-aggregated data.
    When the query doesn't aggregate time series entries, the results are returned in a list of time series results.

Usage Flow

  • Open a session
  • Call session.Query.
    • Run a document query to locate documents whose time series you want to query.
    • Extend the query using LINQ expressions to find and project time series data.
      Start with Select to choose a time series.
  • Retrieve the results using -
    TimeSeriesAggregationResult for aggregated data
    -or-
    TimeSeriesRawResult for non-aggregated data

Usage Samples

  • In this sample, we select a three-days range from the HeartRate time series.
var baseTime = new DateTime(2020, 5, 17, 00, 00, 00);

var query = session.Query<User>()
.Select(q => RavenQuery
.TimeSeries(q, "HeartRates", baseTime, baseTime.AddDays(3))
.ToList());

List<TimeSeriesRawResult> result = query.ToList();
  • The first occurance of Where in the following example, filters documents.
    The second occurance of Where filters entries.
IRavenQueryable<TimeSeriesRawResult> query =
(IRavenQueryable<TimeSeriesRawResult>)session.Query<User>()

// Choose user profiles of users under the age of 30
.Where(u => u.Age < 30)

.Select(q => RavenQuery.TimeSeries(q, "HeartRates", baseline, baseline.AddDays(3))

// Filter entries by tag.
.Where(ts => ts.Tag == "watches/fitbit")

.ToList());

var result = query.ToList();
  • Here, we retrieve a company's stock trade data.
    Note the usage of named values, so we may address trade Volume by name.
// Same query, only unnamed
using (var session = store.OpenSession())
{
IRavenQueryable<TimeSeriesRawResult> query =
session.Query<Company>()
.Where(c => c.Address.City == "New York")
.Select(q => RavenQuery.TimeSeries(q, "StockPrices", baseline, baseline.AddDays(3))
.Where(ts => ts.Tag == "companies/kitchenAppliances")
.ToList());

var result = query.ToList()[0];

day1Volume = result.Results[0].Values[4];
day2Volume = result.Results[1].Values[4];
day3Volume = result.Results[2].Values[4];
}
  • Here, we group heart-rate data of people above the age of 72 into 1-day groups, and retrieve each group's average heart rate and number of measurements.
    The aggregated results are retrieved into an IRavenQueryable<TimeSeriesAggregationResult> array.
var query = session.Query<User>()
.Where(u => u.Age > 72)
.Select(q => RavenQuery.TimeSeries(q, "HeartRates", baseline, baseline.AddDays(10))
.Where(ts => ts.Tag == "watches/fitbit")
.GroupBy(g => g.Days(1))
.Select(g => new
{
Avg = g.Average(),
Cnt = g.Count()
})
.ToList());

List<TimeSeriesAggregationResult> result = query.ToList();

Client Raw RQL Queries

To send a raw RQL query to the server, use session.Advanced.RawQuery.
RawQuery transmits queries to the server without checking or altering their contents, time series contents or otherwise

RQL Queries Syntax

  • session.Advanced.RawQuery
    • Definition
IRawDocumentQuery<T> RawQuery<T>(string query);
  • Parameters

    ParametersTypeDescription
    querystringRaw RQL Query
  • Return Value:

    • IRawDocumentQuery<TimeSeriesAggregationResult> for aggregated data.
      When the query aggregates time series entries, the results are returned in an aggregated array.
    • IRawDocumentQuery<TimeSeriesRawResult> for non-aggregated data.
      When the query doesn't aggregate time series entries, the results are returned in a list of time series results.

RQL Queries Usage Flow

  • Open a session
  • Call session.Advanced.RawQuery
    Pass it your query
  • Retrieve the results into
    TimeSeriesAggregationResult for aggregated data
    -or-
    TimeSeriesRawResult for non-aggregated data

RQL Queries Usage Samples

  • In this sample, a raw RQL query retrieves 24 hours of HeartRate data from users under the age of 30.
    The query does not aggregate data, so we retrieve its results using a TimeSeriesRawResult list.
    We define an offset, to adjust retrieved results to the client's local time-zone.
// May 17 2020, 00:00:00
var baseline = new DateTime(2020, 5, 17, 00, 00, 00);

// Raw query with no aggregation - Declare syntax
IRawDocumentQuery<TimeSeriesRawResult> nonAggregatedRawQuery =
session.Advanced.RawQuery<TimeSeriesRawResult>(@"
declare timeseries getHeartRates(user)
{
from user.HeartRates
between $start and $end
offset '02:00'
}
from Users as u where Age < 30
select getHeartRates(u)
")
.AddParameter("start", baseline)
.AddParameter("end", baseline.AddHours(24));

var nonAggregatedRawQueryResult = nonAggregatedRawQuery.ToList();
  • In this sample, the query aggregates 7 days of HeartRate entries into 1-day groups.
    From each group, two values are selected and projected to the client: the min and max hourly HeartRate values.
    The aggregated results are retrieved using a TimeSeriesAggregationResult array.
var baseline = new DateTime(2020, 5, 17, 00, 00, 00); // May 17 2020, 00:00:00

// Raw Query with aggregation
var query =
session.Advanced.RawQuery<TimeSeriesAggregationResult>(@"
from Users as u
select timeseries(
from HeartRates
between $start and $end
group by '1 days'
select min(), max()
offset '03:00')
")
.AddParameter("start", baseline)
.AddParameter("end", baseline.AddDays(7));

List<TimeSeriesAggregationResult> results = query.ToList();