content/commands/ts.mrevrange.md
{{< note >}} This command's behavior varies in clustered Redis environments. See the [multi-key operations]({{< relref "/develop/using-commands/multi-key-operations" >}}) page for more information. {{< /note >}}
Query a range across multiple time series by filters in the reverse direction. Starting from Redis 8.6, NaN values are included in raw measurement reports (queries without aggregation).
{{< note >}} This command will reply only if the current user has read access to all keys that match the filter. Otherwise, it will reply with "(error): current user doesn't have read permission to one or more keys that match the specified filter". {{< /note >}}
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....
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....
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 named labellabel=value - the time series has a label named label with a value equal to valuelabel=(value1,value2,...) - the time series has a label named label with a value equal to one of the values in the listlabel= - the time series does not have a label named labellabel!=value - the time series does not have a label named label with a value equal to valuelabel!=(value1,value2,...) - the time series does not have a label named label with a value equal to any of the values in the list<note><b>Notes:</b>
label=value or label=(value1,value2,...) is required.type=temperature room=study means that a time series is a temperature time series of a study room.x="y y" or x='(y y,z z)'.
</note>
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.
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.
filters samples by minimum and maximum values. min and max cannot be NaN values.
When used together with AGGREGATION: samples are filtered before being aggregated.
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.
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.
When used without AGGREGATION: limits the number of reported samples per time series.
When used together with AGGREGATION: limits the number of reported buckets.
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:
start or -: The reference timestamp will be the query start interval time (fromTimestamp) which can't be -end or +: The reference timestamp will be the query end interval time (toTimestamp) which can't be +<note><b>Note:</b> When not provided, alignment is set to 0.</note>
per time series, aggregates samples into time buckets, where:
aggregator takes one of the following aggregation types:
aggregator | Description |
|---|---|
avg | Arithmetic mean of all non-NaN values |
sum | Sum of all non-NaN values |
min | Minimum non-NaN value |
max | Maximum non-NaN value |
range | Difference between the maximum and the minimum non-NaN values |
count | Number of non-NaN values |
countNaN | Number of NaN values (since Redis 8.6) |
countAll | Number of values, including NaN and non-NaN (since Redis 8.6) |
first | The non-NaN value with the lowest timestamp in the bucket |
last | The non-NaN value with the highest timestamp in the bucket |
std.p | Population standard deviation of the non-NaN values |
std.s | Sample standard deviation of the non-NaN values |
var.p | Population variance of the non-NaN values |
var.s | Sample variance of the non-NaN values |
twa | Time-weighted average over the bucket's timeframe (ignores NaN values) (since RedisTimeSeries 1.8) |
bucketDuration is 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.
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) |
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.
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.
label is label name. A group is created for all time series that share the same value for this label.
reducer is an aggregation type used to aggregate the results in each group.
reducer | Description |
|---|---|
avg | Arithmetic mean of all non-NaN values; NaN if no such values (since RedisTimeSeries 1.8) |
sum | Sum of all non-NaN values; NaN if no such values |
min | Minimum non-NaN value; NaN if no such values |
max | Maximum non-NaN value; NaN if no such values |
range | Difference between the maximum and the minimum non-NaN values; NaN if no such values (since RedisTimeSeries 1.8) |
count | Number of non-NaN values (since RedisTimeSeries 1.8) |
countNaN | Number of NaN values (since Redis 8.6) |
countAll | Number of values, including NaN and non-NaN (since Redis 8.6) |
std.p | Population standard deviation of the non-NaN values; NaN if no such values (since RedisTimeSeries 1.8) |
std.s | Sample standard deviation of the non-NaN values; NaN if no such values (since RedisTimeSeries 1.8) |
var.p | Population variance of the non-NaN values; NaN if no such values (since RedisTimeSeries 1.8) |
var.s | Sample variance of the non-NaN values; NaN if no such values (since RedisTimeSeries 1.8) |
<note><b>Notes:</b>
<label>=<value>__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")
</note>
<note><b>Note:</b> An MREVRANGE command cannot be part of a transaction when running on a Redis cluster.</note>
Create two stocks and add their prices at three different timestamps.
{{< highlight bash >}} 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
You can now retrieve the maximum stock price per timestamp.
{{< highlight bash >}} 127.0.0.1:6379> TS.MREVRANGE - + WITHLABELS FILTER type=stock GROUPBY type REDUCE max
The 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.
Create two stocks and add their prices at nine different timestamps.
{{< highlight bash >}} 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
Now, 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.
{{< highlight bash >}} 127.0.0.1:6379> TS.MREVRANGE - + WITHLABELS AGGREGATION avg 1000 FILTER type=stock GROUPBY type REDUCE max
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.
{{< highlight bash >}} 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
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.
{{< highlight bash >}} 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
Query all time series with the metric label equal to cpu, but only return the team label.
{{< highlight bash >}} 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
| Redis Software | Redis Cloud | <span style="min-width: 9em; display: table-cell">Notes</span> | |:----------------------|:-----------------|:------| | <span title="Supported">✅ Supported</span> | <span title="Supported">✅ Flexible & Annual</span> <span title="Supported">✅ Free & Fixed</nobr></span> | |
{{< multitabs id="ts-mrevrange-return-info" tab1="RESP2" tab2="RESP3" >}}
If GROUPBY label REDUCE reducer is not specified:
[Array reply]({{< relref "/develop/reference/protocol-spec#arrays" >}}): for each time series matching the specified filters, the following is reported:
WITHLABELS is specified, all labels associated with this time series are reportedSELECTED_LABELS label... is specified, the selected labels are reportedIf GROUPBY label REDUCE reducer is specified:
[Array reply]({{< relref "/develop/reference/protocol-spec#arrays" >}}): for each group of time series matching the specified filters, the following is reported:
label=value where label is the GROUPBY label argumentGROUPBY label argument and value__reducer__ and the reducer argument__source__ and the time series key names separated by ","-tab-sep-
If GROUPBY label REDUCE reducer is not specified:
[Map reply]({{< relref "/develop/reference/protocol-spec#maps" >}}): for each time series matching the specified filters, the following is reported:
WITHLABELS is specified, all labels associated with this time series are reported as a mapSELECTED_LABELS label... is specified, the selected labels are reported as a mapIf GROUPBY label REDUCE reducer is specified:
Similar structure as RESP2 but with map-based organization for labels and metadata, and double values instead of string values.
{{< /multitabs >}}
[TS.MRANGE]({{< relref "commands/ts.mrange/" >}}) | [TS.RANGE]({{< relref "commands/ts.range/" >}}) | [TS.REVRANGE]({{< relref "commands/ts.revrange/" >}})
[RedisTimeSeries]({{< relref "/develop/data-types/timeseries/" >}})