1
0
mirror of https://github.com/redis/go-redis.git synced 2025-09-04 09:22:10 +03:00
Files
go-redis/doctests/timeseries_tut_test.go
andy-stark-redis 421c8a48b4 chore(doc): DOC-5472 time series doc examples (#3443)
* DOC-5472 added and fixed tests up to

* DOC-5472 added agg bucket examples

* DOC-5472 time series doc examples

* DOC-5472 removed black lines above error checks, following feedback

* DOC-5472 fixed param formatting, following feedback

---------

Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
2025-08-04 14:08:10 +03:00

1164 lines
23 KiB
Go

// EXAMPLE: time_series_tutorial
// HIDE_START
package example_commands_test
import (
"context"
"fmt"
"maps"
"math"
"slices"
"sort"
"github.com/redis/go-redis/v9"
)
// HIDE_END
func ExampleClient_timeseries_create() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "thermometer:1", "thermometer:2", "thermometer:3")
// REMOVE_END
// STEP_START create
res1, err := rdb.TSCreate(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> OK
res2, err := rdb.Type(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> TSDB-TYPE
res3, err := rdb.TSInfo(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res3["totalSamples"]) // >>> 0
// STEP_END
// STEP_START create_retention
res4, err := rdb.TSAddWithArgs(
ctx,
"thermometer:2",
1,
10.8,
&redis.TSOptions{
Retention: 100,
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
res5, err := rdb.TSInfo(ctx, "thermometer:2").Result()
if err != nil {
panic(err)
}
fmt.Println(res5["retentionTime"]) // >>> 100
// STEP_END
// STEP_START create_labels
res6, err := rdb.TSAddWithArgs(
ctx,
"thermometer:3",
1,
10.4,
&redis.TSOptions{
Labels: map[string]string{
"location": "UK",
"type": "Mercury",
},
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res6) // >>> 1
res7, err := rdb.TSInfo(ctx, "thermometer:3").Result()
if err != nil {
panic(err)
}
fmt.Println(res7["labels"])
// >>> map[location:UK type:Mercury]
// STEP_END
// Output:
// OK
// TSDB-TYPE
// 0
// 1
// 100
// 1
// map[location:UK type:Mercury]
}
func ExampleClient_timeseries_add() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "thermometer:1", "thermometer:2")
rdb.TSCreate(ctx, "thermometer:1")
rdb.TSCreate(ctx, "thermometer:2")
// REMOVE_END
// STEP_START madd
res1, err := rdb.TSMAdd(ctx, [][]interface{}{
{"thermometer:1", 1, 9.2},
{"thermometer:1", 2, 9.9},
{"thermometer:2", 2, 10.3},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> [1 2 2]
// STEP_END
// STEP_START get
// The last recorded temperature for thermometer:2
// was 10.3 at time 2.
res2, err := rdb.TSGet(ctx, "thermometer:2").Result()
if err != nil {
panic(err)
}
fmt.Println(res2)
// >>> {2 10.3}
// STEP_END
// Output:
// [1 2 2]
// {2 10.3}
}
func ExampleClient_timeseries_range() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "rg:1")
// REMOVE_END
// STEP_START range
// Add 5 data points to a time series named "rg:1".
res1, err := rdb.TSCreate(ctx, "rg:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> OK
res2, err := rdb.TSMAdd(ctx, [][]interface{}{
{"rg:1", 0, 18},
{"rg:1", 1, 14},
{"rg:1", 2, 22},
{"rg:1", 3, 18},
{"rg:1", 4, 24},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> [0 1 2 3 4]
// Retrieve all the data points in ascending order.
// Note: use 0 and `math.MaxInt64` instead of - and +
// to denote the minimum and maximum possible timestamps.
res3, err := rdb.TSRange(ctx, "rg:1", 0, math.MaxInt64).Result()
if err != nil {
panic(err)
}
fmt.Println(res3)
// >>> [{0 18} {1 14} {2 22} {3 18} {4 24}]
// Retrieve data points up to time 1 (inclusive).
res4, err := rdb.TSRange(ctx, "rg:1", 0, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res4)
// >>> [{0 18} {1 14}]
// Retrieve data points from time 3 onwards.
res5, err := rdb.TSRange(ctx, "rg:1", 3, math.MaxInt64).Result()
if err != nil {
panic(err)
}
fmt.Println(res5)
// >>> [{3 18} {4 24}]
// Retrieve all the data points in descending order.
res6, err := rdb.TSRevRange(ctx, "rg:1", 0, math.MaxInt64).Result()
if err != nil {
panic(err)
}
fmt.Println(res6)
// >>> [{4 24} {3 18} {2 22} {1 14} {0 18}]
// Retrieve data points up to time 1 (inclusive), but return them
// in descending order.
res7, err := rdb.TSRevRange(ctx, "rg:1", 0, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res7)
// >>> [{1 14} {0 18}]
// STEP_END
// STEP_START range_filter
res8, err := rdb.TSRangeWithArgs(
ctx,
"rg:1",
0,
math.MaxInt64,
&redis.TSRangeOptions{
FilterByTS: []int{0, 2, 4},
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res8) // >>> [{0 18} {2 22} {4 24}]
res9, err := rdb.TSRevRangeWithArgs(
ctx,
"rg:1",
0,
math.MaxInt64,
&redis.TSRevRangeOptions{
FilterByTS: []int{0, 2, 4},
FilterByValue: []int{20, 25},
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res9) // >>> [{4 24} {2 22}]
res10, err := rdb.TSRevRangeWithArgs(
ctx,
"rg:1",
0,
math.MaxInt64,
&redis.TSRevRangeOptions{
FilterByTS: []int{0, 2, 4},
FilterByValue: []int{22, 22},
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res10) // >>> [{2 22}]
// STEP_END
// Output:
// OK
// [0 1 2 3 4]
// [{0 18} {1 14} {2 22} {3 18} {4 24}]
// [{0 18} {1 14}]
// [{3 18} {4 24}]
// [{4 24} {3 18} {2 22} {1 14} {0 18}]
// [{1 14} {0 18}]
// [{0 18} {2 22} {4 24}]
// [{4 24} {2 22}]
// [{2 22}]
}
func ExampleClient_timeseries_query_multi() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "rg:2", "rg:3", "rg:4")
// REMOVE_END
// STEP_START query_multi
// Create three new "rg:" time series (two in the US
// and one in the UK, with different units) and add some
// data points.
res20, err := rdb.TSCreateWithArgs(ctx, "rg:2", &redis.TSOptions{
Labels: map[string]string{"location": "us", "unit": "cm"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res20) // >>> OK
res21, err := rdb.TSCreateWithArgs(ctx, "rg:3", &redis.TSOptions{
Labels: map[string]string{"location": "us", "unit": "in"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res21) // >>> OK
res22, err := rdb.TSCreateWithArgs(ctx, "rg:4", &redis.TSOptions{
Labels: map[string]string{"location": "uk", "unit": "mm"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res22) // >>> OK
res23, err := rdb.TSMAdd(ctx, [][]interface{}{
{"rg:2", 0, 1.8},
{"rg:3", 0, 0.9},
{"rg:4", 0, 25},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res23) // >>> [0 0 0]
res24, err := rdb.TSMAdd(ctx, [][]interface{}{
{"rg:2", 1, 2.1},
{"rg:3", 1, 0.77},
{"rg:4", 1, 18},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res24) // >>> [1 1 1]
res25, err := rdb.TSMAdd(ctx, [][]interface{}{
{"rg:2", 2, 2.3},
{"rg:3", 2, 1.1},
{"rg:4", 2, 21},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res25) // >>> [2 2 2]
res26, err := rdb.TSMAdd(ctx, [][]interface{}{
{"rg:2", 3, 1.9},
{"rg:3", 3, 0.81},
{"rg:4", 3, 19},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res26) // >>> [3 3 3]
res27, err := rdb.TSMAdd(ctx, [][]interface{}{
{"rg:2", 4, 1.78},
{"rg:3", 4, 0.74},
{"rg:4", 4, 23},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res27) // >>> [4 4 4]
// Retrieve the last data point from each US time series.
res28, err := rdb.TSMGet(ctx, []string{"location=us"}).Result()
if err != nil {
panic(err)
}
res28Keys := slices.Collect(maps.Keys(res28))
sort.Strings(res28Keys)
for _, k := range res28Keys {
labels := res28[k][0].(map[interface{}]interface{})
labelKeys := make([]string, 0, len(labels))
for lk := range labels {
labelKeys = append(labelKeys, lk.(string))
}
sort.Strings(labelKeys)
fmt.Printf("%v:\n", k)
for _, lk := range labelKeys {
fmt.Printf(" %v: %v\n", lk, labels[lk])
}
fmt.Printf(" %v\n", res28[k][1])
}
// >>> rg:2:
// >>> {4 1.78}
// >>> rg:3:
// >>> {4 0.74}
// Retrieve the same data points, but include the `unit`
// label in the results.
res29, err := rdb.TSMGetWithArgs(
ctx,
[]string{"location=us"},
&redis.TSMGetOptions{
SelectedLabels: []interface{}{"unit"},
},
).Result()
if err != nil {
panic(err)
}
res29Keys := slices.Collect(maps.Keys(res29))
sort.Strings(res29Keys)
for _, k := range res29Keys {
labels := res29[k][0].(map[interface{}]interface{})
labelKeys := make([]string, 0, len(labels))
for lk := range labels {
labelKeys = append(labelKeys, lk.(string))
}
sort.Strings(labelKeys)
fmt.Printf("%v:\n", k)
for _, lk := range labelKeys {
fmt.Printf(" %v: %v\n", lk, labels[lk])
}
fmt.Printf(" %v\n", res29[k][1])
}
// >>> rg:2:
// >>> unit: cm
// >>> [4 1.78]
// >>> rg:3:
// >>> unit: in
// >>> [4 0.74]
// Retrieve data points up to time 2 (inclusive) from all
// time series that use millimeters as the unit. Include all
// labels in the results.
// Note that the `aggregators` field is empty if you don't
// specify any aggregators.
res30, err := rdb.TSMRangeWithArgs(
ctx,
0,
2,
[]string{"unit=mm"},
&redis.TSMRangeOptions{
WithLabels: true,
},
).Result()
if err != nil {
panic(err)
}
res30Keys := slices.Collect(maps.Keys(res30))
sort.Strings(res30Keys)
for _, k := range res30Keys {
labels := res30[k][0].(map[interface{}]interface{})
labelKeys := make([]string, 0, len(labels))
for lk := range labels {
labelKeys = append(labelKeys, lk.(string))
}
sort.Strings(labelKeys)
fmt.Printf("%v:\n", k)
for _, lk := range labelKeys {
fmt.Printf(" %v: %v\n", lk, labels[lk])
}
fmt.Printf(" Aggregators: %v\n", res30[k][1])
fmt.Printf(" %v\n", res30[k][2])
}
// >>> rg:4:
// >>> location: uk
// >>> unit: mm
// >>> Aggregators: map[aggregators:[]]
// >>> [{0 25} {1 18} {2 21}]
// Retrieve data points from time 1 to time 3 (inclusive) from
// all time series that use centimeters or millimeters as the unit,
// but only return the `location` label. Return the results
// in descending order of timestamp.
res31, err := rdb.TSMRevRangeWithArgs(
ctx,
1,
3,
[]string{"unit=(cm,mm)"},
&redis.TSMRevRangeOptions{
SelectedLabels: []interface{}{"location"},
},
).Result()
if err != nil {
panic(err)
}
res31Keys := slices.Collect(maps.Keys(res31))
sort.Strings(res31Keys)
for _, k := range res31Keys {
labels := res31[k][0].(map[interface{}]interface{})
labelKeys := make([]string, 0, len(labels))
for lk := range labels {
labelKeys = append(labelKeys, lk.(string))
}
sort.Strings(labelKeys)
fmt.Printf("%v:\n", k)
for _, lk := range labelKeys {
fmt.Printf(" %v: %v\n", lk, labels[lk])
}
fmt.Printf(" Aggregators: %v\n", res31[k][1])
fmt.Printf(" %v\n", res31[k][2])
}
// >>> rg:2:
// >>> location: us
// >>> Aggregators: map[aggregators:[]]
// >>> [{3 1.9} {2 2.3} {1 2.1}]
// >>> rg:4:
// >>> location: uk
// >>> Aggregators: map[aggregators:[]]
// >>> [{3 19} {2 21} {1 18}]
// STEP_END
// Output:
// OK
// OK
// OK
// [0 0 0]
// [1 1 1]
// [2 2 2]
// [3 3 3]
// [4 4 4]
// rg:2:
// [4 1.78]
// rg:3:
// [4 0.74]
// rg:2:
// unit: cm
// [4 1.78]
// rg:3:
// unit: in
// [4 0.74]
// rg:4:
// location: uk
// unit: mm
// Aggregators: map[aggregators:[]]
// [[0 25] [1 18] [2 21]]
// rg:2:
// location: us
// Aggregators: map[aggregators:[]]
// [[3 1.9] [2 2.3] [1 2.1]]
// rg:4:
// location: uk
// Aggregators: map[aggregators:[]]
// [[3 19] [2 21] [1 18]]
}
func ExampleClient_timeseries_aggregation() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "rg:2")
// REMOVE_END
// Setup data for aggregation example
_, err := rdb.TSCreateWithArgs(ctx, "rg:2", &redis.TSOptions{
Labels: map[string]string{"location": "us", "unit": "cm"},
}).Result()
if err != nil {
panic(err)
}
_, err = rdb.TSMAdd(ctx, [][]interface{}{
{"rg:2", 0, 1.8},
{"rg:2", 1, 2.1},
{"rg:2", 2, 2.3},
{"rg:2", 3, 1.9},
{"rg:2", 4, 1.78},
}).Result()
if err != nil {
panic(err)
}
// STEP_START agg
res32, err := rdb.TSRangeWithArgs(
ctx,
"rg:2",
0,
math.MaxInt64,
&redis.TSRangeOptions{
Aggregator: redis.Avg,
BucketDuration: 2,
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res32)
// >>> [{0 1.9500000000000002} {2 2.0999999999999996} {4 1.78}]
// STEP_END
// Output:
// [{0 1.9500000000000002} {2 2.0999999999999996} {4 1.78}]
}
func ExampleClient_timeseries_agg_bucket() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "sensor3")
// REMOVE_END
// STEP_START agg_bucket
res1, err := rdb.TSCreate(ctx, "sensor3").Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> OK
res2, err := rdb.TSMAdd(ctx, [][]interface{}{
{"sensor3", 10, 1000},
{"sensor3", 20, 2000},
{"sensor3", 30, 3000},
{"sensor3", 40, 4000},
{"sensor3", 50, 5000},
{"sensor3", 60, 6000},
{"sensor3", 70, 7000},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> [10 20 30 40 50 60 70]
res3, err := rdb.TSRangeWithArgs(
ctx,
"sensor3",
10,
70,
&redis.TSRangeOptions{
Aggregator: redis.Min,
BucketDuration: 25,
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> [{0 1000} {25 3000} {50 5000}]
// STEP_END
// STEP_START agg_align
res4, err := rdb.TSRangeWithArgs(
ctx,
"sensor3",
10,
70,
&redis.TSRangeOptions{
Aggregator: redis.Min,
BucketDuration: 25,
Align: "START",
},
).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> [{10 1000} {35 4000} {60 6000}]
// STEP_END
// Output:
// OK
// [10 20 30 40 50 60 70]
// [{0 1000} {25 3000} {50 5000}]
// [{10 1000} {35 4000} {60 6000}]
}
func ExampleClient_timeseries_aggmulti() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "wind:1", "wind:2", "wind:3", "wind:4")
// REMOVE_END
// STEP_START agg_multi
res37, err := rdb.TSCreateWithArgs(ctx, "wind:1", &redis.TSOptions{
Labels: map[string]string{"country": "uk"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res37) // >>> OK
res38, err := rdb.TSCreateWithArgs(ctx, "wind:2", &redis.TSOptions{
Labels: map[string]string{"country": "uk"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res38) // >>> OK
res39, err := rdb.TSCreateWithArgs(ctx, "wind:3", &redis.TSOptions{
Labels: map[string]string{"country": "us"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res39) // >>> OK
res40, err := rdb.TSCreateWithArgs(ctx, "wind:4", &redis.TSOptions{
Labels: map[string]string{"country": "us"},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res40) // >>> OK
res41, err := rdb.TSMAdd(ctx, [][]interface{}{
{"wind:1", 1, 12},
{"wind:2", 1, 18},
{"wind:3", 1, 5},
{"wind:4", 1, 20},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res41) // >>> [1 1 1 1]
res42, err := rdb.TSMAdd(ctx, [][]interface{}{
{"wind:1", 2, 14},
{"wind:2", 2, 21},
{"wind:3", 2, 4},
{"wind:4", 2, 25},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res42) // >>> [2 2 2 2]
res43, err := rdb.TSMAdd(ctx, [][]interface{}{
{"wind:1", 3, 10},
{"wind:2", 3, 24},
{"wind:3", 3, 8},
{"wind:4", 3, 18},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res43) // >>> [3 3 3 3]
// The result pairs contain the timestamp and the maximum sample value
// for the country at that timestamp.
res44, err := rdb.TSMRangeWithArgs(
ctx,
0,
math.MaxInt64,
[]string{"country=(us,uk)"},
&redis.TSMRangeOptions{
GroupByLabel: "country",
Reducer: "max",
},
).Result()
if err != nil {
panic(err)
}
res44Keys := slices.Collect(maps.Keys(res44))
sort.Strings(res44Keys)
for _, k := range res44Keys {
labels := res44[k][0].(map[interface{}]interface{})
labelKeys := make([]string, 0, len(labels))
for lk := range labels {
labelKeys = append(labelKeys, lk.(string))
}
sort.Strings(labelKeys)
fmt.Printf("%v:\n", k)
for _, lk := range labelKeys {
fmt.Printf(" %v: %v\n", lk, labels[lk])
}
fmt.Printf(" %v\n", res44[k][1])
fmt.Printf(" %v\n", res44[k][2])
fmt.Printf(" %v\n", res44[k][3])
}
// >>> country=uk:
// >>> map[reducers:[max]]
// >>> map[sources:[wind:1 wind:2]]
// >>> [[1 18] [2 21] [3 24]]
// >>> country=us:
// >>> map[reducers:[max]]
// >>> map[sources:[wind:3 wind:4]]
// >>> [[1 20] [2 25] [3 18]]
// The result pairs contain the timestamp and the average sample value
// for the country at that timestamp.
res45, err := rdb.TSMRangeWithArgs(
ctx,
0,
math.MaxInt64,
[]string{"country=(us,uk)"},
&redis.TSMRangeOptions{
GroupByLabel: "country",
Reducer: "avg",
},
).Result()
if err != nil {
panic(err)
}
res45Keys := slices.Collect(maps.Keys(res45))
sort.Strings(res45Keys)
for _, k := range res45Keys {
labels := res45[k][0].(map[interface{}]interface{})
labelKeys := make([]string, 0, len(labels))
for lk := range labels {
labelKeys = append(labelKeys, lk.(string))
}
sort.Strings(labelKeys)
fmt.Printf("%v:\n", k)
for _, lk := range labelKeys {
fmt.Printf(" %v: %v\n", lk, labels[lk])
}
fmt.Printf(" %v\n", res45[k][1])
fmt.Printf(" %v\n", res45[k][2])
fmt.Printf(" %v\n", res45[k][3])
}
// >>> country=uk:
// >>> map[reducers:[avg]]
// >>> map[sources:[wind:1 wind:2]]
// >>> [[1 15] [2 17.5] [3 17]]
// >>> country=us:
// >>> map[reducers:[avg]]
// >>> map[sources:[wind:3 wind:4]]
// >>> [[1 12.5] [2 14.5] [3 13]]
// STEP_END
// Output:
// OK
// OK
// OK
// OK
// [1 1 1 1]
// [2 2 2 2]
// [3 3 3 3]
// country=uk:
// map[reducers:[max]]
// map[sources:[wind:1 wind:2]]
// [[1 18] [2 21] [3 24]]
// country=us:
// map[reducers:[max]]
// map[sources:[wind:3 wind:4]]
// [[1 20] [2 25] [3 18]]
// country=uk:
// map[reducers:[avg]]
// map[sources:[wind:1 wind:2]]
// [[1 15] [2 17.5] [3 17]]
// country=us:
// map[reducers:[avg]]
// map[sources:[wind:3 wind:4]]
// [[1 12.5] [2 14.5] [3 13]]
}
func ExampleClient_timeseries_compaction() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "hyg:1", "hyg:compacted")
// REMOVE_END
// STEP_START create_compaction
res45, err := rdb.TSCreate(ctx, "hyg:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res45) // >>> OK
res46, err := rdb.TSCreate(ctx, "hyg:compacted").Result()
if err != nil {
panic(err)
}
fmt.Println(res46) // >>> OK
res47, err := rdb.TSCreateRule(
ctx, "hyg:1", "hyg:compacted", redis.Min, 3,
).Result()
if err != nil {
panic(err)
}
fmt.Println(res47) // >>> OK
res48, err := rdb.TSInfo(ctx, "hyg:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res48["rules"]) // >>> [[hyg:compacted 3 MIN 0]]
res49, err := rdb.TSInfo(ctx, "hyg:compacted").Result()
if err != nil {
panic(err)
}
fmt.Println(res49["sourceKey"]) // >>> hyg:1
// STEP_END
// STEP_START comp_add
res50, err := rdb.TSMAdd(ctx, [][]interface{}{
{"hyg:1", 0, 75},
{"hyg:1", 1, 77},
{"hyg:1", 2, 78},
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res50) // >>> [0 1 2]
res51, err := rdb.TSRange(
ctx, "hyg:compacted", 0, math.MaxInt64,
).Result()
if err != nil {
panic(err)
}
fmt.Println(res51) // >>> []
res52, err := rdb.TSAdd(ctx, "hyg:1", 3, 79).Result()
if err != nil {
panic(err)
}
fmt.Println(res52) // >>> 3
res53, err := rdb.TSRange(
ctx, "hyg:compacted", 0, math.MaxInt64,
).Result()
if err != nil {
panic(err)
}
fmt.Println(res53) // >>> [{0 75}]
// STEP_END
// Output:
// OK
// OK
// OK
// map[hyg:compacted:[3 MIN 0]]
// hyg:1
// [0 1 2]
// []
// 3
// [{0 75}]
}
func ExampleClient_timeseries_delete() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// REMOVE_START
// make sure we are working with fresh database
rdb.FlushDB(ctx)
rdb.Del(ctx, "thermometer:1")
// Setup initial data
rdb.TSCreate(ctx, "thermometer:1")
rdb.TSMAdd(ctx, [][]interface{}{
{"thermometer:1", 1, 9.2},
{"thermometer:1", 2, 9.9},
})
// REMOVE_END
// STEP_START del
res54, err := rdb.TSInfo(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res54["totalSamples"]) // >>> 2
fmt.Println(res54["firstTimestamp"]) // >>> 1
fmt.Println(res54["lastTimestamp"]) // >>> 2
res55, err := rdb.TSAdd(ctx, "thermometer:1", 3, 9.7).Result()
if err != nil {
panic(err)
}
fmt.Println(res55) // >>> 3
res56, err := rdb.TSInfo(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res56["totalSamples"]) // >>> 3
fmt.Println(res56["firstTimestamp"]) // >>> 1
fmt.Println(res56["lastTimestamp"]) // >>> 3
res57, err := rdb.TSDel(ctx, "thermometer:1", 1, 2).Result()
if err != nil {
panic(err)
}
fmt.Println(res57) // >>> 2
res58, err := rdb.TSInfo(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res58["totalSamples"]) // >>> 1
fmt.Println(res58["firstTimestamp"]) // >>> 3
fmt.Println(res58["lastTimestamp"]) // >>> 3
res59, err := rdb.TSDel(ctx, "thermometer:1", 3, 3).Result()
if err != nil {
panic(err)
}
fmt.Println(res59) // >>> 1
res60, err := rdb.TSInfo(ctx, "thermometer:1").Result()
if err != nil {
panic(err)
}
fmt.Println(res60["totalSamples"]) // >>> 0
// STEP_END
// Output:
// 2
// 1
// 2
// 3
// 3
// 1
// 3
// 2
// 1
// 3
// 3
// 1
// 0
}