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
, andTag
. - One index-field obtained from the time series segment header:
EmployeeID
. - One index-field obtained from the loaded employee document:
EmployeeName
.
- Three index-fields obtained from the "HeartRates" time series entries:
-
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.
class TsIndex(AbstractTimeSeriesIndexCreationTask):
# The index-entry:
# ===============
class IndexEntry:
def __init__(
self,
bpm: float = None,
date: datetime = None,
tag: str = None,
employee_id: str = None,
employee_name: str = None,
):
# The index-fields:
# =================
self.bpm = bpm
self.date = date
self.tag = tag
self.employee_id = employee_id
self.employee_name = employee_name
def __init__(self):
super().__init__()
self.map = """
from ts in timeSeries.Employees.HeartRates
from entry in ts.Entries
let employee = LoadDocument(ts.DocumentId, "Employees")
select new
{
bpm = entry.Values[0],
date = entry.Timestamp.Date,
tag = entry.Tag,
employee_id = ts.DocumentId,
employee_name = 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".
with store.open_session() as session:
results = list(session.query_index_type(self.TsIndex, self.TsIndex.IndexEntry))
# Access results:
entry_result = results[0]
employee_name = entry_result.employee_name
bmp = entry_result.bpm
with store.open_session() as session:
results = list(session.advanced.raw_query("from index 'TsIndex'", self.TsIndex.IndexEntry))
from index "TsIndex"
Filter query results:
In this example, time series entries are filtered by the query.
The query predicate is applied to the index-fields.
with store.open_session() as session:
results = list(
session.query_index_type(self.TsIndex, self.TsIndex.IndexEntry)
.where_equals("employee_name", "Robert King")
.and_also()
.where_greater_than("bpm", 85)
)
with store.open_session() as session:
results = list(
session.advanced.raw_query(
"from index 'TsIndex' where employee_name == 'Robert King' and bpm > 85.0",
self.TsIndex.IndexEntry,
)
)
from index "TsIndex"
where EmployeeName == "Robert King" and BPM > 85.0
Order query results:
Results can be ordered by any of the index-fields.
with store.open_session() as session:
results = list(
session.query_index_type(self.TsIndex, self.TsIndex.IndexEntry)
.where_less_than("bpm", 58)
.order_by_descending("date")
)
with store.open_session() as session:
results = list(
session.advanced.raw_query(
"from index 'TsIndex' where bpm < 58.0 order by date desc",
self.TsIndex.IndexEntry,
)
)
from index "TsIndex"
where BPM < 58.0
order by Date desc
Project results:
-
Instead of returning the entire
TsIndex.IndexEntry
object for each result item,
you can return only partial fields. -
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.
with store.open_session() as session:
results = list(
session.query_index_type(self.TsIndex, self.TsIndex.IndexEntry)
.where_greater_than("bpm", 100)
.select_fields(self.EmployeeDetails, "employee_id")
.distinct()
)
# This class is used when projecting index-fields via DocumentQuery
class EmployeeDetails:
def __init__(self, employee_name: str = None, employee_id: str = None):
self.employee_name = employee_name
self.employee_id = employee_id
with store.open_session() as session:
results = list(
session.advanced.raw_query(
"from index 'TsIndex' where bpm > 100.0 select distinct employee_id",
self.TsIndex.IndexEntry,
)
)
from index "TsIndex"
where BPM > 100.0
select distinct EmployeeID
Syntax
-
def query( self, source: Optional[Query] = None, object_type: Optional[Type[_T]] = None ) -> DocumentQuery[_T]: ...
-
def document_query( self, index_name: str = None, collection_name: str = None, object_type: Type[_T] = None, is_map_reduce: bool = False, ) -> DocumentQuery[_T]: ...