Named Time Series Values
-
A time series entry consists of a timestamp, one or more values, and an optional tag.
Each value can be given a name to indicate what it represents, such as "Temperature", "Humidity", "Pressure", etc. -
Referring to these values by their names in time series methods (such as
append
,get
, etc.)
makes your code more readable and easier to manage. -
In order for the Studio to present the time series values by their names, as can be seen here,
you need to register the named values on the server. -
In this page:
Named values
-
Many time series are populated with multiple values for each measurement.
For example, each GPS measurement in a route-tracking time series would include at least two values:
latitude and longitude. -
You can ease the management of multi-value time series by -
- Naming time series values in custom classes.
- Calling time series methods with your custom types to address and manage values by name.
Define time series class with named values
To define a class with named values, add the static property TIME_SERIES_VALUES
to the class.
E.g.:
class RoutePoint {
// Add the following static param:
static TIME_SERIES_VALUES = ["latitude", "longitude"];
// The Latitude and Longitude properties will contain the time series entry values.
// The names for these values will be "latitude" and "longitude" respectively.
constructor(
latitude = 0,
longitude = 0
) {
Object.assign(this, {
latitude,
longitude
});
}
}
The class can then be used by time series methods like append:
const baseTime = new Date();
const oneHour = 60 * 60 * 1000;
let nextHour = new Date(baseTime.getTime() + oneHour);
const tsf = session.timeSeriesFor("users/john", "RoutePoints", RoutePoint);
const routePoint = new RoutePoint();
routePoint.latitude = 40.712776;
routePoint.longitude = -74.005974;
// Append coordinates using the routePoint object
tsf.append(nextHour, routePoint, "devices/Navigator");
await session.saveChanges();
Examples
-
In this example, we define a StockPrice class and use it when appending StockPrice entries.
class StockPrice { // Define the names for the entry values static TIME_SERIES_VALUES = ["open", "close", "high", "low", "volume"]; constructor( open = 0, close = 0, high = 0, low = 0, volume = 0 ) { Object.assign(this, { open, close, high, low, volume }); } }
const session = documentStore.openSession(); await session.store(new User("John"), "users/john"); // Get an instance of 'timeSeriesFor', pass: // * the document ID // * the time series name // * the class that will hold the entry's values const tsf = session.timeSeriesFor("users/john", "StockPrices", StockPrice); const optionalTag = "companies/kitchenAppliances"; const baseTime = new Date(); baseTime.setUTCHours(0); const oneDay = 24 * 60 * 60 * 1000; // Provide the multiple values via the StockPrice class const price1 = new StockPrice(); price1.open = 52; price1.close = 54; price1.high = 63.5; price1.low = 51.4; price1.volume = 9824; // Call 'append' with the custom StockPrice class let nextDay = new Date(baseTime.getTime() + oneDay); tsf.append(nextDay, price1, optionalTag); const price2 = new StockPrice(); price2.open = 54; price2.close = 55; price2.high = 61.5; price2.low = 49.4; price2.volume = 8400; nextDay = new Date(baseTime.getTime() + oneDay * 2); tsf.append(nextDay, price2, optionalTag); const price3 = new StockPrice(); price3.open = 55; price3.close = 57; price3.high = 65.5; price3.low = 50; price3.volume = 9020; nextDay = new Date(baseTime.getTime() + oneDay * 3); tsf.append(nextDay, price3, optionalTag); await session.saveChanges();
-
In this example, we get StockPrice values by name and check whether a stock's closing-time prices are ascending over time.
let goingUp = false; const allEntries = await session .timeSeriesFor("users/john", "StockPrices") .get(); // Call 'asTypedEntry' to be able to access the entry's values by their names // Pass the class type (StockPrice) const typedEntry1 = allEntries[0].asTypedEntry(StockPrice); // Access the entry value by its StockPrice class property name (close) const closePriceDay1 = typedEntry1.value.close; const typedEntry2 = allEntries[1].asTypedEntry(StockPrice); const closePriceDay2 = typedEntry2.value.close; const typedEntry3 = allEntries[2].asTypedEntry(StockPrice); const closePriceDay3 = typedEntry3.value.close; // Check if the stock's closing price is rising if ((closePriceDay2 > closePriceDay1) && (closePriceDay3 > closePriceDay2)) { goingUp = true; }
-
In this query, we use the custom StockPrice type so we can address trade Volume by name.
const oneDay = 24 * 60 * 60 * 1000; const startTime = new Date(); const endTime = new Date(startTime.getTime() + 3 * oneDay); // Note: the 'where' clause must come after the 'between' clause const tsQueryText = ` from StockPrices between $start and $end where Tag == "AppleTech"`; const query = session.query({ collection: "companies" }) .whereEquals("address.city", "New York") .selectTimeSeries(b => b.raw(tsQueryText), TimeSeriesRawResult) .addParameter("start", startTime) .addParameter("end", endTime); // Execute the query: const results = await query.all(); // Access entries results: const tsEntries = results[0].results; // Call 'asTypedEntry' to be able to access the entry's values by their names // Pass the class type (StockPrice) const volumeDay1 = tsEntries[0].asTypedEntry(StockPrice).value.volume; const volumeDay2 = tsEntries[1].asTypedEntry(StockPrice).value.volume; const volumeDay3 = tsEntries[2].asTypedEntry(StockPrice).value.volume;
from "companies" where address.city = $p0 select timeseries( from StockPrices between $start and $end where Tag == "AppleTech") { "p0":"New York", "start":"2024-06-04T06:02:39.826Z", "end":"2024-06-07T06:02:39.826Z" }
Register time series named values
Registering a custom time series type on the server stores this information in the database record.
This allows the Studio to present time series values by name when you view and manage them.
Usage
To register a time series type, call documentStore.timeSeries.register
, e.g.:
// Register the named values for the 'StockPrices' series on the server
await documentStore.timeSeries.register("Users",
"StockPrices", ["open", "close", "high", "low", "volume"]);
The time series entries will be listed in the Studio under their corresponding named values:
Time series entries with named values
The named values can be managed from the Time Series Settings View in the Studio:
The time series settings view
Syntax
// Available overloads:
// ====================
register(collection, name, valueNames);
register(collectionClass, name, valueNames);
register(collectionClass, timeSeriesEntryClass);
register(collectionClass, timeSeriesEntryClass, name);
Parameter | Type | Description |
---|---|---|
collection | string |
The time series collection name |
name | string |
Time series name |
valueNames | string[] |
Names to register (name per value) |
collectionClass | object |
The collection class |
timeSeriesEntryClass | object |
The custom time series entry class |