Skip to main content

Querying Time Series Indexes

  • Time series index:

    • STATIC-time-series-indexes can be defined from the Client API or using Studio.
      Such an index can be queried in the same way as a regular index that indexes documents.
      (See Querying an index).

    • AUTO-time-series-indexes are Not generated automatically by the server when making a time series query.

  • The contents of the query results:

    • Unlike a document index, where the source data are your JSON documents,
      the source data for a time series index are the time series entries within the documents.

    • When querying a document index:
      the resulting objects are the document entities (unless results are projected).

    • When querying a time series index:
      each item in the results is of the type defined by the index-entry in the index definition,
      (unless results are projected). The documents themselves are not returned.

  • In this page:

Sample Index

  • The following is a time series map-index that will be used in the query examples throughout this article.

  • Each index-entry consists of:

    • Three index-fields obtained from the "HeartRates" time series entries: BPM, Date, and Tag.
    • One index-field obtained from the time series segment header: EmployeeID.
    • One index-field obtained from the loaded employee document: EmployeeName.
  • When querying this time series index:

    • The resulting items correspond to the time series entries that match the query predicate.
    • Each item in the results will be of type TsIndex.IndexEntry, which is the index-entry.
      Different result types may be returned when the query projects the results.
public class TsIndex : AbstractTimeSeriesIndexCreationTask<Employee>
{
// The index-entry:
// ================
public class IndexEntry
{
// The index-fields:
// =================
public double BPM { get; set; }
public DateTime Date { get; set; }
public string Tag { get; set; }
public string EmployeeID { get; set; }
public string EmployeeName { get; set; }
}

public TsIndex()
{
AddMap("HeartRates", timeSeries =>
from segment in timeSeries
from entry in segment.Entries

let employee = LoadDocument<Employee>(segment.DocumentId)

// Define the content of the index-fields:
// =======================================
select new IndexEntry()
{
BPM = entry.Values[0],
Date = entry.Timestamp,
Tag = entry.Tag,
EmployeeID = segment.DocumentId,
EmployeeName = employee.FirstName + " " + employee.LastName
});
}
}

Querying the index

Query all time series entries:

No filtering is applied in this query.
Results will include ALL entries from time series "HeartRates".

using (var session = store.OpenSession())
{
List<TsIndex.IndexEntry> results = session
// Query the index
.Query<TsIndex.IndexEntry, TsIndex>()
// Query for all entries w/o any filtering
.ToList();

// Access results:
TsIndex.IndexEntry entryResult = results[0];
string employeeName = entryResult.EmployeeName;
double BPM = entryResult.BPM;
}

Filter query results:

In this example, time series entries are filtered by the query.
The query predicate is applied to the index-fields.

using (var session = store.OpenSession())
{
List<TsIndex.IndexEntry> results = session
.Query<TsIndex.IndexEntry, TsIndex>()
// Retrieve only time series entries with high BPM values for a specific employee
.Where(x => x.EmployeeName == "Robert King" && x.BPM > 85)
.ToList();
}

Order query results:

Results can be ordered by any of the index-fields.

using (var session = store.OpenSession())
{
List<TsIndex.IndexEntry> results = session
.Query<TsIndex.IndexEntry, TsIndex>()
// Retrieve time series entries where employees had a low BPM value
.Where(x => x.BPM < 58)
// Order by the 'Date' index-field (descending order)
.OrderByDescending(x => x.Date)
.ToList();
}

Project results:

  • Instead of returning the entire TsIndex.IndexEntry object for each result item,
    you can return only partial fields.

  • Learn more about projecting query results in Project Index Query Results.

  • In this example, we query for time series entries with a very high BPM value.
    We retrieve entries with BPM value > 100 but return only the EmployeeID for each entry.

using (var session = store.OpenSession())
{
List<string> results = session
.Query<TsIndex.IndexEntry, TsIndex>()
.Where(x => x.BPM > 100)
// Return only the EmployeeID index-field in the results
.Select(x => x.EmployeeID)
// Optionally: call 'Distinct' to remove duplicates from results
.Distinct()
.ToList();
}

Syntax

  • session.Query
IRavenQueryable<T> Query<T, TIndexCreator>() where TIndexCreator 
: AbstractCommonApiForIndexes, new();
  • DocumentQuery
IDocumentQuery<T> DocumentQuery<T, TIndexCreator>() where TIndexCreator 
: AbstractCommonApiForIndexes, new();
ParameterDescription
TThe results class
TIndexCreatorIndex