mirror of
https://github.com/redis/go-redis.git
synced 2025-07-04 14:02:29 +03:00
547 lines
9.9 KiB
Go
547 lines
9.9 KiB
Go
// EXAMPLE: vecset_tutorial
|
|
// HIDE_START
|
|
package example_commands_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// HIDE_END
|
|
|
|
func ExampleClient_vectorset() {
|
|
ctx := context.Background()
|
|
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: "localhost:6379",
|
|
Password: "", // no password set
|
|
DB: 0, // use default DB
|
|
})
|
|
|
|
defer rdb.Close()
|
|
// REMOVE_START
|
|
rdb.Del(ctx, "points", "quantSetQ8", "quantSetNoQ", "quantSetBin", "setNotReduced", "setReduced")
|
|
// REMOVE_END
|
|
|
|
// STEP_START vadd
|
|
res1, err := rdb.VAdd(ctx, "points", "pt:A",
|
|
&redis.VectorValues{Val: []float64{1.0, 1.0}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res1) // >>> true
|
|
|
|
res2, err := rdb.VAdd(ctx, "points", "pt:B",
|
|
&redis.VectorValues{Val: []float64{-1.0, -1.0}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res2) // >>> true
|
|
|
|
res3, err := rdb.VAdd(ctx, "points", "pt:C",
|
|
&redis.VectorValues{Val: []float64{-1.0, 1.0}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res3) // >>> true
|
|
|
|
res4, err := rdb.VAdd(ctx, "points", "pt:D",
|
|
&redis.VectorValues{Val: []float64{1.0, -1.0}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res4) // >>> true
|
|
|
|
res5, err := rdb.VAdd(ctx, "points", "pt:E",
|
|
&redis.VectorValues{Val: []float64{1.0, 0.0}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res5) // >>> true
|
|
|
|
res6, err := rdb.Type(ctx, "points").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res6) // >>> vectorset
|
|
// STEP_END
|
|
|
|
// STEP_START vcardvdim
|
|
res7, err := rdb.VCard(ctx, "points").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res7) // >>> 5
|
|
|
|
res8, err := rdb.VDim(ctx, "points").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res8) // >>> 2
|
|
// STEP_END
|
|
|
|
// STEP_START vemb
|
|
res9, err := rdb.VEmb(ctx, "points", "pt:A", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res9) // >>> [0.9999999403953552 0.9999999403953552]
|
|
|
|
res10, err := rdb.VEmb(ctx, "points", "pt:B", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res10) // >>> [-0.9999999403953552 -0.9999999403953552]
|
|
|
|
res11, err := rdb.VEmb(ctx, "points", "pt:C", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res11) // >>> [-0.9999999403953552 0.9999999403953552]
|
|
|
|
res12, err := rdb.VEmb(ctx, "points", "pt:D", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res12) // >>> [0.9999999403953552 -0.9999999403953552]
|
|
|
|
res13, err := rdb.VEmb(ctx, "points", "pt:E", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res13) // >>> [1 0]
|
|
// STEP_END
|
|
|
|
// STEP_START attr
|
|
attrs := map[string]interface{}{
|
|
"name": "Point A",
|
|
"description": "First point added",
|
|
}
|
|
|
|
res14, err := rdb.VSetAttr(ctx, "points", "pt:A", attrs).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res14) // >>> true
|
|
|
|
res15, err := rdb.VGetAttr(ctx, "points", "pt:A").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res15)
|
|
// >>> {"description":"First point added","name":"Point A"}
|
|
|
|
res16, err := rdb.VClearAttributes(ctx, "points", "pt:A").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res16) // >>> true
|
|
|
|
// `VGetAttr()` returns an error if the attribute doesn't exist.
|
|
_, err = rdb.VGetAttr(ctx, "points", "pt:A").Result()
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
// STEP_END
|
|
|
|
// STEP_START vrem
|
|
res18, err := rdb.VAdd(ctx, "points", "pt:F",
|
|
&redis.VectorValues{Val: []float64{0.0, 0.0}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res18) // >>> true
|
|
|
|
res19, err := rdb.VCard(ctx, "points").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res19) // >>> 6
|
|
|
|
res20, err := rdb.VRem(ctx, "points", "pt:F").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res20) // >>> true
|
|
|
|
res21, err := rdb.VCard(ctx, "points").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res21) // >>> 5
|
|
// STEP_END
|
|
|
|
// STEP_START vsim_basic
|
|
res22, err := rdb.VSim(ctx, "points",
|
|
&redis.VectorValues{Val: []float64{0.9, 0.1}},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res22) // >>> [pt:E pt:A pt:D pt:C pt:B]
|
|
// STEP_END
|
|
|
|
// STEP_START vsim_options
|
|
res23, err := rdb.VSimWithArgsWithScores(
|
|
ctx,
|
|
"points",
|
|
&redis.VectorRef{Name: "pt:A"},
|
|
&redis.VSimArgs{Count: 4},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
sort.Slice(res23, func(i, j int) bool {
|
|
return res23[i].Name < res23[j].Name
|
|
})
|
|
|
|
fmt.Println(res23)
|
|
// >>> [{pt:A 1} {pt:C 0.5} {pt:D 0.5} {pt:E 0.8535534143447876}]
|
|
// STEP_END
|
|
|
|
// STEP_START vsim_filter
|
|
// Set attributes for filtering
|
|
res24, err := rdb.VSetAttr(ctx, "points", "pt:A",
|
|
map[string]interface{}{
|
|
"size": "large",
|
|
"price": 18.99,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res24) // >>> true
|
|
|
|
res25, err := rdb.VSetAttr(ctx, "points", "pt:B",
|
|
map[string]interface{}{
|
|
"size": "large",
|
|
"price": 35.99,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res25) // >>> true
|
|
|
|
res26, err := rdb.VSetAttr(ctx, "points", "pt:C",
|
|
map[string]interface{}{
|
|
"size": "large",
|
|
"price": 25.99,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res26) // >>> true
|
|
|
|
res27, err := rdb.VSetAttr(ctx, "points", "pt:D",
|
|
map[string]interface{}{
|
|
"size": "small",
|
|
"price": 21.00,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res27) // >>> true
|
|
|
|
res28, err := rdb.VSetAttr(ctx, "points", "pt:E",
|
|
map[string]interface{}{
|
|
"size": "small",
|
|
"price": 17.75,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res28) // >>> true
|
|
|
|
// Return elements in order of distance from point A whose
|
|
// `size` attribute is `large`.
|
|
res29, err := rdb.VSimWithArgs(ctx, "points",
|
|
&redis.VectorRef{Name: "pt:A"},
|
|
&redis.VSimArgs{Filter: `.size == "large"`},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res29) // >>> [pt:A pt:C pt:B]
|
|
|
|
// Return elements in order of distance from point A whose size is
|
|
// `large` and whose price is greater than 20.00.
|
|
res30, err := rdb.VSimWithArgs(ctx, "points",
|
|
&redis.VectorRef{Name: "pt:A"},
|
|
&redis.VSimArgs{Filter: `.size == "large" && .price > 20.00`},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res30) // >>> [pt:C pt:B]
|
|
// STEP_END
|
|
|
|
// Output:
|
|
// true
|
|
// true
|
|
// true
|
|
// true
|
|
// true
|
|
// vectorset
|
|
// 5
|
|
// 2
|
|
// [0.9999999403953552 0.9999999403953552]
|
|
// [-0.9999999403953552 -0.9999999403953552]
|
|
// [-0.9999999403953552 0.9999999403953552]
|
|
// [0.9999999403953552 -0.9999999403953552]
|
|
// [1 0]
|
|
// true
|
|
// {"description":"First point added","name":"Point A"}
|
|
// true
|
|
// redis: nil
|
|
// true
|
|
// 6
|
|
// true
|
|
// 5
|
|
// [pt:E pt:A pt:D pt:C pt:B]
|
|
// [{pt:A 1} {pt:C 0.5} {pt:D 0.5} {pt:E 0.8535534143447876}]
|
|
// true
|
|
// true
|
|
// true
|
|
// true
|
|
// true
|
|
// [pt:A pt:C pt:B]
|
|
// [pt:C pt:B]
|
|
}
|
|
|
|
func ExampleClient_vectorset_quantization() {
|
|
ctx := context.Background()
|
|
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: "localhost:6379",
|
|
Password: "", // no password set
|
|
DB: 0, // use default DB
|
|
})
|
|
|
|
defer rdb.Close()
|
|
// REMOVE_START
|
|
rdb.Del(ctx, "quantSetQ8", "quantSetNoQ", "quantSetBin")
|
|
// REMOVE_END
|
|
|
|
// STEP_START add_quant
|
|
// Add with Q8 quantization
|
|
vecQ := &redis.VectorValues{Val: []float64{1.262185, 1.958231}}
|
|
|
|
res1, err := rdb.VAddWithArgs(ctx, "quantSetQ8", "quantElement", vecQ,
|
|
&redis.VAddArgs{
|
|
Q8: true,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res1) // >>> true
|
|
|
|
embQ8, err := rdb.VEmb(ctx, "quantSetQ8", "quantElement", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("Q8 embedding: %v\n", embQ8)
|
|
// >>> Q8 embedding: [1.2621850967407227 1.9582309722900391]
|
|
|
|
// Add with NOQUANT option
|
|
res2, err := rdb.VAddWithArgs(ctx, "quantSetNoQ", "quantElement", vecQ,
|
|
&redis.VAddArgs{
|
|
NoQuant: true,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res2) // >>> true
|
|
|
|
embNoQ, err := rdb.VEmb(ctx, "quantSetNoQ", "quantElement", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("NOQUANT embedding: %v\n", embNoQ)
|
|
// >>> NOQUANT embedding: [1.262185 1.958231]
|
|
|
|
// Add with BIN quantization
|
|
res3, err := rdb.VAddWithArgs(ctx, "quantSetBin", "quantElement", vecQ,
|
|
&redis.VAddArgs{
|
|
Bin: true,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res3) // >>> true
|
|
|
|
embBin, err := rdb.VEmb(ctx, "quantSetBin", "quantElement", false).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("BIN embedding: %v\n", embBin)
|
|
// >>> BIN embedding: [1 1]
|
|
// STEP_END
|
|
|
|
// Output:
|
|
// true
|
|
// Q8 embedding: [1.2643694877624512 1.958230972290039]
|
|
// true
|
|
// NOQUANT embedding: [1.262184977531433 1.958230972290039]
|
|
// true
|
|
// BIN embedding: [1 1]
|
|
}
|
|
|
|
func ExampleClient_vectorset_dimension_reduction() {
|
|
ctx := context.Background()
|
|
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: "localhost:6379",
|
|
Password: "", // no password set
|
|
DB: 0, // use default DB
|
|
})
|
|
|
|
defer rdb.Close()
|
|
// REMOVE_START
|
|
rdb.Del(ctx, "setNotReduced", "setReduced")
|
|
// REMOVE_END
|
|
|
|
// STEP_START add_reduce
|
|
// Create a vector with 300 dimensions
|
|
values := make([]float64, 300)
|
|
|
|
for i := 0; i < 300; i++ {
|
|
values[i] = float64(i) / 299
|
|
}
|
|
|
|
vecLarge := &redis.VectorValues{Val: values}
|
|
|
|
// Add without reduction
|
|
res1, err := rdb.VAdd(ctx, "setNotReduced", "element", vecLarge).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res1) // >>> true
|
|
|
|
dim1, err := rdb.VDim(ctx, "setNotReduced").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("Dimension without reduction: %d\n", dim1)
|
|
// >>> Dimension without reduction: 300
|
|
|
|
// Add with reduction to 100 dimensions
|
|
res2, err := rdb.VAddWithArgs(ctx, "setReduced", "element", vecLarge,
|
|
&redis.VAddArgs{
|
|
Reduce: 100,
|
|
},
|
|
).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(res2) // >>> true
|
|
|
|
dim2, err := rdb.VDim(ctx, "setReduced").Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("Dimension after reduction: %d\n", dim2)
|
|
// >>> Dimension after reduction: 100
|
|
// STEP_END
|
|
|
|
// Output:
|
|
// true
|
|
// Dimension without reduction: 300
|
|
// true
|
|
// Dimension after reduction: 100
|
|
}
|