TS.MREVRANGE
TS.MREVRANGE fromTimestamp toTimestamp [LATEST] [FILTER_BY_TS ts...] [FILTER_BY_VALUE min max] [WITHLABELS | <SELECTED_LABELS label...>] [COUNT count] [[ALIGN align] AGGREGATION aggregator bucketDuration [BUCKETTIMESTAMP bt] [EMPTY]] FILTER filterExpr... [GROUPBY label REDUCE reducer]
- Available in:
- Redis Open Source / TimeSeries 1.4.0
- Time complexity:
- O(n/m+k) where n = Number of data points, m = Chunk size (data points per chunk), k = Number of data points that are in the requested ranges
- ACL categories:
-
@timeseries,@read,@slow,
Query a range across multiple time series by filters in the reverse direction.
Required arguments
fromTimestamp
is the start timestamp for the range query (integer Unix timestamp in milliseconds) or - to denote the timestamp of the earliest sample among all the time series that passes FILTER filterExpr....
toTimestamp
is the end timestamp for the range query (integer Unix timestamp in milliseconds) or + to denote the timestamp of the latest sample among all the time series that passes FILTER filterExpr....
FILTER filterExpr...
filters time series based on their labels and label values. Each filter expression has one of the following syntaxes:
label!=- the time series has a label namedlabellabel=value- the time series has a label namedlabelwith a value equal tovaluelabel=(value1,value2,...)- the time series has a label namedlabelwith a value equal to one of the values in the listlabel=- the time series does not have a label namedlabellabel!=value- the time series does not have a label namedlabelwith a value equal tovaluelabel!=(value1,value2,...)- the time series does not have a label namedlabelwith a value equal to any of the values in the list
- At least one filter expression with a syntax
label=valueorlabel=(value1,value2,...)is required. - Filter expressions are conjunctive. For example, the filter
type=temperature room=studymeans that a time series is a temperature time series of a study room. - Whitespaces are unallowed in a filter expression except between quotes or double quotes in values - e.g.,
x="y y"orx='(y y,z z)'.
Optional arguments
LATEST (since RedisTimeSeries v1.8)
is used when a time series is a compaction. With LATEST, TS.MREVRANGE also reports the compacted value of the latest (possibly partial) bucket, given that this bucket's start time falls within [fromTimestamp, toTimestamp]. Without LATEST, TS.MREVRANGE does not report the latest (possibly partial) bucket. When a time series is not a compaction, LATEST is ignored.
The data in the latest bucket of a compaction is possibly partial. A bucket is closed and compacted only upon the arrival of a new sample that opens a new latest bucket. There are cases, however, when the compacted value of the latest (possibly partial) bucket is also required. In such a case, use LATEST.
FILTER_BY_TS ts... (since RedisTimeSeries v1.6)
filters samples by a list of specific timestamps. A sample passes the filter if its exact timestamp is specified and falls within [fromTimestamp, toTimestamp].
When used together with AGGREGATION: samples are filtered before being aggregated.
FILTER_BY_VALUE min max (since RedisTimeSeries v1.6)
filters samples by minimum and maximum values.
When used together with AGGREGATION: samples are filtered before being aggregated.
WITHLABELS
includes in the reply all label-value pairs representing metadata labels of the time series.
If WITHLABELS or SELECTED_LABELS are not specified, by default, an empty list is reported as label-value pairs.
SELECTED_LABELS label... (since RedisTimeSeries v1.6)
returns a subset of the label-value pairs that represent metadata labels of the time series.
Use when a large number of labels exists per series, but only the values of some of the labels are required.
If WITHLABELS or SELECTED_LABELS are not specified, by default, an empty list is reported as label-value pairs.
COUNT count
When used without AGGREGATION: limits the number of reported samples per time series.
When used together with AGGREGATION: limits the number of reported buckets.
ALIGN align (since RedisTimeSeries v1.6)
is a time bucket alignment control for AGGREGATION. It controls the time bucket timestamps by changing the reference timestamp on which a bucket is defined.
Values include:
startor-: The reference timestamp will be the query start interval time (fromTimestamp) which can't be-endor+: The reference timestamp will be the query end interval time (toTimestamp) which can't be+- A specific timestamp: align the reference timestamp to a specific time
0.
AGGREGATION aggregator bucketDuration
per time series, aggregates samples into time buckets, where:
-
aggregatortakes one of the following aggregation types:aggregatorDescription avgArithmetic mean of all values sumSum of all values minMinimum value maxMaximum value rangeDifference between maximum value and minimum value countNumber of values firstValue with lowest timestamp in the bucket lastValue with highest timestamp in the bucket std.pPopulation standard deviation of the values std.sSample standard deviation of the values var.pPopulation variance of the values var.sSample variance of the values twaTime-weighted average over the bucket's timeframe (since RedisTimeSeries v1.8) -
bucketDurationis duration of each bucket, in milliseconds.
Without ALIGN, bucket start times are multiples of bucketDuration.
With ALIGN align, bucket start times are multiples of bucketDuration with remainder align % bucketDuration.
The first bucket start time is less than or equal to fromTimestamp.
[BUCKETTIMESTAMP bt] (since RedisTimeSeries v1.8)
controls how bucket timestamps are reported.
bt |
Timestamp reported for each bucket |
|---|---|
- or start |
the bucket's start time (default) |
+ or end |
the bucket's end time |
~ or mid |
the bucket's mid time (rounded down if not an integer) |
[EMPTY] (since RedisTimeSeries v1.8)
is a flag, which, when specified, reports aggregations also for empty buckets.
aggregator |
Value reported for each empty bucket |
|---|---|
sum, count |
0 |
last |
The value of the last sample before the bucket's start. NaN when no such sample. |
twa |
Average value over the bucket's timeframe based on linear interpolation of the last sample before the bucket's start and the first sample after the bucket's end. NaN when no such samples. |
min, max, range, avg, first, std.p, std.s |
NaN |
Regardless of the values of fromTimestamp and toTimestamp, no data is reported for buckets that end before the earliest sample or begin after the latest sample in the time series.
GROUPBY label REDUCE reducer (since RedisTimeSeries v1.6)
splits time series into groups, each group contains time series that share the same value for the provided label name, then aggregates results in each group.
When combined with AGGREGATION the GROUPBY/REDUCE is applied post aggregation stage.
-
labelis label name. A group is created for all time series that share the same value for this label. -
reduceris an aggregation type used to aggregate the results in each group.reducerDescription avgArithmetic mean of all non-NaN values (since RedisTimeSeries v1.8) sumSum of all non-NaN values minMinimum non-NaN value maxMaximum non-NaN value rangeDifference between maximum non-NaN value and minimum non-NaN value (since RedisTimeSeries v1.8) countNumber of non-NaN values (since RedisTimeSeries v1.8) std.pPopulation standard deviation of all non-NaN values (since RedisTimeSeries v1.8) std.sSample standard deviation of all non-NaN values (since RedisTimeSeries v1.8) var.pPopulation variance of all non-NaN values (since RedisTimeSeries v1.8) var.sSample variance of all non-NaN values (since RedisTimeSeries v1.8)
- The produced time series is named
<label>=<value> - The produced time series contains two labels with these label array structures:
__reducer__, the reducer used (e.g.,"count")__source__, the list of time series keys used to compute the grouped series (e.g.,"key1,key2,key3")
MREVRANGE command cannot be part of a transaction when running on a Redis cluster.
Examples
Retrieve maximum stock price per timestamp
Create two stocks and add their prices at three different timestamps.
127.0.0.1:6379> TS.CREATE stock:A LABELS type stock name A
OK
127.0.0.1:6379> TS.CREATE stock:B LABELS type stock name B
OK
127.0.0.1:6379> TS.MADD stock:A 1000 100 stock:A 1010 110 stock:A 1020 120
1) (integer) 1000
2) (integer) 1010
3) (integer) 1020
127.0.0.1:6379> TS.MADD stock:B 1000 120 stock:B 1010 110 stock:B 1020 100
1) (integer) 1000
2) (integer) 1010
3) (integer) 1020You can now retrieve the maximum stock price per timestamp.
127.0.0.1:6379> TS.MREVRANGE - + WITHLABELS FILTER type=stock GROUPBY type REDUCE max
1) 1) "type=stock"
2) 1) 1) "type"
2) "stock"
2) 1) "__reducer__"
2) "max"
3) 1) "__source__"
2) "stock:A,stock:B"
3) 1) 1) (integer) 1020
2) 120
2) 1) (integer) 1010
2) 110
3) 1) (integer) 1000
2) 120The FILTER type=stock clause returns a single time series representing stock prices. The GROUPBY type REDUCE max clause splits the time series into groups with identical type values, and then, for each timestamp, aggregates all series that share the same type value using the max aggregator.
Calculate average stock price and retrieve maximum average
Create two stocks and add their prices at nine different timestamps.
127.0.0.1:6379> TS.CREATE stock:A LABELS type stock name A
OK
127.0.0.1:6379> TS.CREATE stock:B LABELS type stock name B
OK
127.0.0.1:6379> TS.MADD stock:A 1000 100 stock:A 1010 110 stock:A 1020 120
1) (integer) 1000
2) (integer) 1010
3) (integer) 1020
127.0.0.1:6379> TS.MADD stock:B 1000 120 stock:B 1010 110 stock:B 1020 100
1) (integer) 1000
2) (integer) 1010
3) (integer) 1020
127.0.0.1:6379> TS.MADD stock:A 2000 200 stock:A 2010 210 stock:A 2020 220
1) (integer) 2000
2) (integer) 2010
3) (integer) 2020
127.0.0.1:6379> TS.MADD stock:B 2000 220 stock:B 2010 210 stock:B 2020 200
1) (integer) 2000
2) (integer) 2010
3) (integer) 2020
127.0.0.1:6379> TS.MADD stock:A 3000 300 stock:A 3010 310 stock:A 3020 320
1) (integer) 3000
2) (integer) 3010
3) (integer) 3020
127.0.0.1:6379> TS.MADD stock:B 3000 320 stock:B 3010 310 stock:B 3020 300
1) (integer) 3000
2) (integer) 3010
3) (integer) 3020Now, for each stock, calculate the average stock price per a 1000-millisecond timeframe, and then retrieve the stock with the maximum average for that timeframe in reverse direction.
127.0.0.1:6379> TS.MREVRANGE - + WITHLABELS AGGREGATION avg 1000 FILTER type=stock GROUPBY type REDUCE max
1) 1) "type=stock"
2) 1) 1) "type"
2) "stock"
2) 1) "__reducer__"
2) "max"
3) 1) "__source__"
2) "stock:A,stock:B"
3) 1) 1) (integer) 3000
2) 310
2) 1) (integer) 2000
2) 210
3) 1) (integer) 1000
2) 110Group query results
Query all time series with the metric label equal to cpu, then group the time series by the value of their metric_name label value and for each group return the maximum value and the time series keys (source) with that value.
127.0.0.1:6379> TS.ADD ts1 1548149180000 90 labels metric cpu metric_name system
(integer) 1548149180000
127.0.0.1:6379> TS.ADD ts1 1548149185000 45
(integer) 1548149185000
127.0.0.1:6379> TS.ADD ts2 1548149180000 99 labels metric cpu metric_name user
(integer) 1548149180000
127.0.0.1:6379> TS.MREVRANGE - + WITHLABELS FILTER metric=cpu GROUPBY metric_name REDUCE max
1) 1) "metric_name=system"
2) 1) 1) "metric_name"
2) "system"
2) 1) "__reducer__"
2) "max"
3) 1) "__source__"
2) "ts1"
3) 1) 1) (integer) 1548149185000
2) 45
2) 1) (integer) 1548149180000
2) 90
2) 1) "metric_name=user"
2) 1) 1) "metric_name"
2) "user"
2) 1) "__reducer__"
2) "max"
3) 1) "__source__"
2) "ts2"
3) 1) 1) (integer) 1548149180000
2) 99Filter query by value
Query all time series with the metric label equal to cpu, then filter values larger or equal to 90.0 and smaller or equal to 100.0.
127.0.0.1:6379> TS.ADD ts1 1548149180000 90 labels metric cpu metric_name system
(integer) 1548149180000
127.0.0.1:6379> TS.ADD ts1 1548149185000 45
(integer) 1548149185000
127.0.0.1:6379> TS.ADD ts2 1548149180000 99 labels metric cpu metric_name user
(integer) 1548149180000
127.0.0.1:6379> TS.MREVRANGE - + FILTER_BY_VALUE 90 100 WITHLABELS FILTER metric=cpu
1) 1) "ts1"
2) 1) 1) "metric"
2) "cpu"
2) 1) "metric_name"
2) "system"
3) 1) 1) (integer) 1548149180000
2) 90
2) 1) "ts2"
2) 1) 1) "metric"
2) "cpu"
2) 1) "metric_name"
2) "user"
3) 1) 1) (integer) 1548149180000
2) 99Query using a label
Query all time series with the metric label equal to cpu, but only return the team label.
127.0.0.1:6379> TS.ADD ts1 1548149180000 90 labels metric cpu metric_name system team NY
(integer) 1548149180000
127.0.0.1:6379> TS.ADD ts1 1548149185000 45
(integer) 1548149185000
127.0.0.1:6379> TS.ADD ts2 1548149180000 99 labels metric cpu metric_name user team SF
(integer) 1548149180000
127.0.0.1:6379> TS.MREVRANGE - + SELECTED_LABELS team FILTER metric=cpu
1) 1) "ts1"
2) 1) 1) "team"
2) (nil)
3) 1) 1) (integer) 1548149185000
2) 45
2) 1) (integer) 1548149180000
2) 90
2) 1) "ts2"
2) 1) 1) "team"
2) (nil)
3) 1) 1) (integer) 1548149180000
2) 99Return information
If GROUPBY label REDUCE reducer is not specified:
Array reply: for each time series matching the specified filters, the following is reported:
- Bulk string reply: The time series key name
- Array reply: label-value pairs (Bulk string reply, Bulk string reply)
- By default, an empty array is reported
- If
WITHLABELSis specified, all labels associated with this time series are reported - If
SELECTED_LABELS label...is specified, the selected labels are reported
- Array reply: timestamp-value pairs (Integer reply, Simple string reply) representing all samples/aggregations matching the range in reverse chronological order
If GROUPBY label REDUCE reducer is specified:
Array reply: for each group of time series matching the specified filters, the following is reported:
- Bulk string reply with the format
label=valuewherelabelis theGROUPBYlabel argument - Array reply: a single pair (Bulk string reply, Bulk string reply): the
GROUPBYlabel argument and value - Array reply: a single pair (Bulk string reply, Bulk string reply): the string
__reducer__and the reducer argument - Array reply: a single pair (Bulk string reply, Bulk string reply): the string
__source__and the time series key names separated by "," - Array reply: timestamp-value pairs (Integer reply, Simple string reply) representing all samples/aggregations matching the range in reverse chronological order
See also
TS.MRANGE | TS.RANGE | TS.REVRANGE