Redis vector sets
Introduction to Redis vector sets
Vector set is a new data type that is currently in preview and may be subject to change.
Vector sets are a data type similar to sorted sets, but instead of a score, vector set elements have a string representation of a vector. Vector sets allow you to add items to a set, and then either:
- retrieve a subset of items that are the most similar to a specified vector, or
- retrieve a subset of items that are the most similar to the vector of an element that is already part of the vector set.
Vector sets also provide for optional filtered search. You can associate attributes with all or some elements in a vector set, and then use the FILTER
option of the VSIM
command to retrieve items similar to a given vector while applying simple mathematical filters to those attributes. Here's a sample filter: ".year > 1950"
.
The following commands are available for vector sets:
- VADD - add an element to a vector set, creating a new set if it didn't already exist.
- VCARD - retrieve the number of elements in a vector set.
- VDIM - retrieve the dimension of the vectors in a vector set.
- VEMB - retrieve the approximate vector associated with a vector set element.
- VGETATTR - retrieve the attributes of a vector set element.
- VINFO - retrieve metadata and internal details about a vector set, including size, dimensions, quantization type, and graph structure.
- VISMEMBER - check if an element exists in a vector set.
- VLINKS - retrieve the neighbors of a specified element in a vector set; the connections for each layer of the HNSW graph.
- VRANDMEMBER - retrieve random elements of a vector set.
- VREM - remove an element from a vector set.
- VSETATTR - set or replace attributes on a vector set element.
- VSIM - retrieve elements similar to a given vector or element with optional filtering.
Endianness considerations for FP32 format
When using the FP32 blob format with vector set commands like VADD
and VSIM
, the binary data must be encoded in little-endian byte order. This is important for cross-platform compatibility, as some ARM variants and other architectures may use different endianness.
If your platform uses big-endian or mixed-endian encoding, you have two options:
- Manually convert the byte order to little-endian before passing the blob to Redis.
- Use the
VALUES
syntax instead, which accepts floating-point numbers as strings and is platform-independent.
Examples
The following examples give an overview of how to use vector sets. For clarity, we will use a set of two-dimensional vectors that represent points in the Cartesian coordinate plane. However, in real use cases, the vectors will typically represent text embeddings and have hundreds of dimensions. See Redis for AI for more information about using text embeddings.
The points we will use are A: (1.0, 1.0), B: (-1.0, -1.0), C: (-1.0, 1.0), D: (1.0. -1.0), and E: (1.0, 0), shown in the diagram below.
Basic operations
Start by adding the point vectors to a set called points
using
VADD
. This also creates the vector set object.
The TYPE
command returns a type of vectorset
for this object.
> VADD points VALUES 2 1.0 1.0 pt:A
(integer) 1
> VADD points VALUES 2 -1.0 -1.0 pt:B
(integer) 1
> VADD points VALUES 2 -1.0 1.0 pt:C
(integer) 1
> VADD points VALUES 2 1.0 -1.0 pt:D
(integer) 1
> VADD points VALUES 2 1.0 0 pt:E
(integer) 1
> TYPE points
vectorset
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Get the number of elements in the set (also known as the cardinality of the set)
using VCARD
and the number of dimensions of
the vectors using VDIM
:
> VCARD points
(integer) 5
> VDIM points
(integer) 2
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Get the coordinate values from the elements using VEMB
.
Note that the values will not typically be the exact values you supplied when you added
the vector because
quantization
is applied to improve performance.
> VEMB points pt:A
1) "0.9999999403953552"
2) "0.9999999403953552"
9> VEMB points pt:B
1) "-0.9999999403953552"
2) "-0.9999999403953552"
> VEMB points pt:C
1) "-0.9999999403953552"
2) "0.9999999403953552"
> VEMB points pt:D
1) "0.9999999403953552"
2) "-0.9999999403953552"
> VEMB points pt:E
1) "1"
2) "0"
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Set and retrieve an element's JSON attribute data using
VSETATTR
and VGETATTR
. You can also pass an empty string
to VSETATTR
to delete the attribute data:
> VSETATTR points pt:A "{\"name\": \"Point A\", \"description\": \"First point added\"}"
(integer) 1
> VGETATTR points pt:A
"{\"name\": \"Point A\", \"description\": \"First point added\"}"
> VSETATTR points pt:A ""
(integer) 1
> VGETATTR points pt:A
(nil)
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Remove an unwanted element with VREM
> VADD points VALUES 2 0 0 pt:F
(integer) 1
127.0.0.1:6379> VCARD points
(integer) 6
127.0.0.1:6379> VREM points pt:F
(integer) 1
127.0.0.1:6379> VCARD points
(integer) 5
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Vector similarity search
Use VSIM
to rank the points in order of their vector distance from a sample point:
> VSIM points values 2 0.9 0.1
1) "pt:E"
2) "pt:A"
3) "pt:D"
4) "pt:C"
5) "pt:B"
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Find the four elements that are closest to point A and show their distance "scores":
> VSIM points ELE pt:A WITHSCORES COUNT 4
1) "pt:A"
2) "1"
3) "pt:E"
4) "0.8535534143447876"
5) "pt:C"
6) "0.5"
7) "pt:D"
8) "0.5"
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
Add some JSON attributes and use filter expressions to include them in the search:
> VSETATTR points pt:A "{\"size\":\"large\",\"price\": 18.99}"
(integer) 1
> VSETATTR points pt:B "{\"size\":\"large\",\"price\": 35.99}"
(integer) 1
> VSETATTR points pt:C "{\"size\":\"large\",\"price\": 25.99}"
(integer) 1
> VSETATTR points pt:D "{\"size\":\"small\",\"price\": 21.00}"
(integer) 1
> VSETATTR points pt:E "{\"size\":\"small\",\"price\": 17.75}"
(integer) 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
> VSIM points ELE pt:A FILTER '.size == "large"'
1) "pt:A"
2) "pt:C"
3) "pt:B"
# Return elements in order of distance from point A whose size is
# `large` and whose price is greater than 20.00.
> VSIM points ELE pt:A FILTER '.size == "large" && .price > 20.00'
1) "pt:C"
2) "pt:B"
"""
Code samples for Vector set doc pages:
https://redis.io/docs/latest/develop/data-types/vector-sets/
"""
import redis
from redis.commands.vectorset.commands import (
QuantizationOptions
)
r = redis.Redis(decode_responses=True)
res1 = r.vset().vadd("points", [1.0, 1.0], "pt:A")
print(res1) # >>> 1
res2 = r.vset().vadd("points", [-1.0, -1.0], "pt:B")
print(res2) # >>> 1
res3 = r.vset().vadd("points", [-1.0, 1.0], "pt:C")
print(res3) # >>> 1
res4 = r.vset().vadd("points", [1.0, -1.0], "pt:D")
print(res4) # >>> 1
res5 = r.vset().vadd("points", [1.0, 0], "pt:E")
print(res5) # >>> 1
res6 = r.type("points")
print(res6) # >>> vectorset
res7 = r.vset().vcard("points")
print(res7) # >>> 5
res8 = r.vset().vdim("points")
print(res8) # >>> 2
res9 = r.vset().vemb("points", "pt:A")
print(res9) # >>> [0.9999999403953552, 0.9999999403953552]
res10 = r.vset().vemb("points", "pt:B")
print(res10) # >>> [-0.9999999403953552, -0.9999999403953552]
res11 = r.vset().vemb("points", "pt:C")
print(res11) # >>> [-0.9999999403953552, 0.9999999403953552]
res12 = r.vset().vemb("points", "pt:D")
print(res12) # >>> [0.9999999403953552, -0.9999999403953552]
res13 = r.vset().vemb("points", "pt:E")
print(res13) # >>> [1, 0]
res14 = r.vset().vsetattr("points", "pt:A", {
"name": "Point A",
"description": "First point added"
})
print(res14) # >>> 1
res15 = r.vset().vgetattr("points", "pt:A")
print(res15)
# >>> {'name': 'Point A', 'description': 'First point added'}
res16 = r.vset().vsetattr("points", "pt:A", "")
print(res16) # >>> 1
res17 = r.vset().vgetattr("points", "pt:A")
print(res17) # >>> None
res18 = r.vset().vadd("points", [0, 0], "pt:F")
print(res18) # >>> 1
res19 = r.vset().vcard("points")
print(res19) # >>> 6
res20 = r.vset().vrem("points", "pt:F")
print(res20) # >>> 1
res21 = r.vset().vcard("points")
print(res21) # >>> 5
res22 = r.vset().vsim("points", [0.9, 0.1])
print(res22)
# >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
res23 = r.vset().vsim(
"points", "pt:A",
with_scores=True,
count=4
)
print(res23)
# >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
res24 = r.vset().vsetattr("points", "pt:A", {
"size": "large",
"price": 18.99
})
print(res24) # >>> 1
res25 = r.vset().vsetattr("points", "pt:B", {
"size": "large",
"price": 35.99
})
print(res25) # >>> 1
res26 = r.vset().vsetattr("points", "pt:C", {
"size": "large",
"price": 25.99
})
print(res26) # >>> 1
res27 = r.vset().vsetattr("points", "pt:D", {
"size": "small",
"price": 21.00
})
print(res27) # >>> 1
res28 = r.vset().vsetattr("points", "pt:E", {
"size": "small",
"price": 17.75
})
print(res28) # >>> 1
# Return elements in order of distance from point A whose
# `size` attribute is `large`.
res29 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large"'
)
print(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 = r.vset().vsim(
"points", "pt:A",
filter='.size == "large" && .price > 20.00'
)
print(res30) # >>> ['pt:C', 'pt:B']
# Import `QuantizationOptions` enum using:
#
# from redis.commands.vectorset.commands import (
# QuantizationOptions
# )
res31 = r.vset().vadd(
"quantSetQ8", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.Q8
)
print(res31) # >>> 1
res32 = r.vset().vemb("quantSetQ8", "quantElement")
print(f"Q8: {res32}")
# >>> Q8: [1.2643694877624512, 1.958230972290039]
res33 = r.vset().vadd(
"quantSetNoQ", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.NOQUANT
)
print(res33) # >>> 1
res34 = r.vset().vemb("quantSetNoQ", "quantElement")
print(f"NOQUANT: {res34}")
# >>> NOQUANT: [1.262184977531433, 1.958230972290039]
res35 = r.vset().vadd(
"quantSetBin", [1.262185, 1.958231],
"quantElement",
quantization=QuantizationOptions.BIN
)
print(res35) # >>> 1
res36 = r.vset().vemb("quantSetBin", "quantElement")
print(f"BIN: {res36}")
# >>> BIN: [1, 1]
# Create a list of 300 arbitrary values.
values = [x / 299 for x in range(300)]
res37 = r.vset().vadd(
"setNotReduced",
values,
"element"
)
print(res37) # >>> 1
res38 = r.vset().vdim("setNotReduced")
print(res38) # >>> 300
res39 = r.vset().vadd(
"setReduced",
values,
"element",
reduce_dim=100
)
print(res39) # >>> 1
res40 = r.vset().vdim("setReduced") # >>> 100
print(res40)
import { createClient } from 'redis';
const client = createClient({
RESP: 3 // Required for vector set commands
});
await client.connect();
const res1 = await client.vAdd("points", [1.0, 1.0], "pt:A");
console.log(res1); // >>> true
const res2 = await client.vAdd("points", [-1.0, -1.0], "pt:B");
console.log(res2); // >>> true
const res3 = await client.vAdd("points", [-1.0, 1.0], "pt:C");
console.log(res3); // >>> true
const res4 = await client.vAdd("points", [1.0, -1.0], "pt:D");
console.log(res4); // >>> true
const res5 = await client.vAdd("points", [1.0, 0], "pt:E");
console.log(res5); // >>> true
const res6 = await client.type("points");
console.log(res6); // >>> vectorset
const res7 = await client.vCard("points");
console.log(res7); // >>> 5
const res8 = await client.vDim("points");
console.log(res8); // >>> 2
const res9 = await client.vEmb("points", "pt:A");
console.log(res9); // >>> [0.9999999403953552, 0.9999999403953552]
const res10 = await client.vEmb("points", "pt:B");
console.log(res10); // >>> [-0.9999999403953552, -0.9999999403953552]
const res11 = await client.vEmb("points", "pt:C");
console.log(res11); // >>> [-0.9999999403953552, 0.9999999403953552]
const res12 = await client.vEmb("points", "pt:D");
console.log(res12); // >>> [0.9999999403953552, -0.9999999403953552]
const res13 = await client.vEmb("points", "pt:E");
console.log(res13); // >>> [1, 0]
const res14 = await client.vSetAttr("points", "pt:A", {
name: "Point A",
description: "First point added"
});
console.log(res14); // >>> true
const res15 = await client.vGetAttr("points", "pt:A");
console.log(res15);
// >>> {name: 'Point A', description: 'First point added'}
const res16 = await client.vSetAttr("points", "pt:A", "");
console.log(res16); // >>> true
const res17 = await client.vGetAttr("points", "pt:A");
console.log(res17); // >>> null
const res18 = await client.vAdd("points", [0, 0], "pt:F");
console.log(res18); // >>> true
const res19 = await client.vCard("points");
console.log(res19); // >>> 6
const res20 = await client.vRem("points", "pt:F");
console.log(res20); // >>> true
const res21 = await client.vCard("points");
console.log(res21); // >>> 5
const res22 = await client.vSim("points", [0.9, 0.1]);
console.log(res22);
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
const res23 = await client.vSimWithScores("points", "pt:A", { COUNT: 4 });
console.log(res23);
// >>> {pt:A: 1.0, pt:E: 0.8535534143447876, pt:D: 0.5, pt:C: 0.5}
const res24 = await client.vSetAttr("points", "pt:A", {
size: "large",
price: 18.99
});
console.log(res24); // >>> true
const res25 = await client.vSetAttr("points", "pt:B", {
size: "large",
price: 35.99
});
console.log(res25); // >>> true
const res26 = await client.vSetAttr("points", "pt:C", {
size: "large",
price: 25.99
});
console.log(res26); // >>> true
const res27 = await client.vSetAttr("points", "pt:D", {
size: "small",
price: 21.00
});
console.log(res27); // >>> true
const res28 = await client.vSetAttr("points", "pt:E", {
size: "small",
price: 17.75
});
console.log(res28); // >>> true
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
const res29 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large"'
});
console.log(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.
const res30 = await client.vSim("points", "pt:A", {
FILTER: '.size == "large" && .price > 20.00'
});
console.log(res30); // >>> ['pt:C', 'pt:B']
const res31 = await client.vAdd("quantSetQ8", [1.262185, 1.958231], "quantElement", {
QUANT: 'Q8'
});
console.log(res31); // >>> true
const res32 = await client.vEmb("quantSetQ8", "quantElement");
console.log(`Q8: ${res32}`);
// >>> Q8: [1.2643694877624512, 1.958230972290039]
const res33 = await client.vAdd("quantSetNoQ", [1.262185, 1.958231], "quantElement", {
QUANT: 'NOQUANT'
});
console.log(res33); // >>> true
const res34 = await client.vEmb("quantSetNoQ", "quantElement");
console.log(`NOQUANT: ${res34}`);
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
const res35 = await client.vAdd("quantSetBin", [1.262185, 1.958231], "quantElement", {
QUANT: 'BIN'
});
console.log(res35); // >>> true
const res36 = await client.vEmb("quantSetBin", "quantElement");
console.log(`BIN: ${res36}`);
// >>> BIN: [1, 1]
// Create a list of 300 arbitrary values.
const values = Array.from({length: 300}, (_, x) => x / 299);
const res37 = await client.vAdd("setNotReduced", values, "element");
console.log(res37); // >>> true
const res38 = await client.vDim("setNotReduced");
console.log(res38); // >>> 300
const res39 = await client.vAdd("setReduced", values, "element", {
REDUCE: 100
});
console.log(res39); // >>> true
const res40 = await client.vDim("setReduced");
console.log(res40); // >>> 100
await client.quit();
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.params.VAddParams;
import redis.clients.jedis.params.VSimParams;
import java.util.*;
public class VectorSetExample {
public void run() {
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
boolean res1 = jedis.vadd("points", new float[] { 1.0f, 1.0f }, "pt:A");
System.out.println(res1); // >>> true
boolean res2 = jedis.vadd("points", new float[] { -1.0f, -1.0f }, "pt:B");
System.out.println(res2); // >>> true
boolean res3 = jedis.vadd("points", new float[] { -1.0f, 1.0f }, "pt:C");
System.out.println(res3); // >>> true
boolean res4 = jedis.vadd("points", new float[] { 1.0f, -1.0f }, "pt:D");
System.out.println(res4); // >>> true
boolean res5 = jedis.vadd("points", new float[] { 1.0f, 0.0f }, "pt:E");
System.out.println(res5); // >>> true
String res6 = jedis.type("points");
System.out.println(res6); // >>> vectorset
long res7 = jedis.vcard("points");
System.out.println(res7); // >>> 5
long res8 = jedis.vdim("points");
System.out.println(res8); // >>> 2
List<Double> res9 = jedis.vemb("points", "pt:A");
System.out.println(res9); // >>> [0.9999999..., 0.9999999...]
List<Double> res10 = jedis.vemb("points", "pt:B");
System.out.println(res10); // >>> [-0.9999999..., -0.9999999...]
List<Double> res11 = jedis.vemb("points", "pt:C");
System.out.println(res11); // >>> [-0.9999999..., 0.9999999...]
List<Double> res12 = jedis.vemb("points", "pt:D");
System.out.println(res12); // >>> [0.9999999..., -0.9999999...]
List<Double> res13 = jedis.vemb("points", "pt:E");
System.out.println(res13); // >>> [1, 0]
boolean res14 = jedis.vsetattr("points", "pt:A",
"{\"name\":\"Point A\",\"description\":\"First point added\"}");
System.out.println(res14); // >>> true
String res15 = jedis.vgetattr("points", "pt:A");
System.out.println(res15);
// >>> {"name":"Point A","description":"First point added"}
boolean res16 = jedis.vsetattr("points", "pt:A", "");
System.out.println(res16); // >>> true
String res17 = jedis.vgetattr("points", "pt:A");
System.out.println(res17); // >>> null
boolean res18 = jedis.vadd("points", new float[] { 0.0f, 0.0f }, "pt:F");
System.out.println(res18); // >>> true
long res19 = jedis.vcard("points");
System.out.println(res19); // >>> 6
boolean res20 = jedis.vrem("points", "pt:F");
System.out.println(res20); // >>> true
long res21 = jedis.vcard("points");
System.out.println(res21); // >>> 5
List<String> res22 = jedis.vsim("points", new float[] { 0.9f, 0.1f });
System.out.println(res22);
// >>> ["pt:E", "pt:A", "pt:D", "pt:C", "pt:B"]
Map<String, Double> res23 = jedis.vsimByElementWithScores("points", "pt:A",
new VSimParams().count(4));
System.out.println(res23);
// >>> {pt:A=1.0, pt:E≈0.85355, pt:D=0.5, pt:C=0.5}
boolean res24 = jedis.vsetattr("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
System.out.println(res24); // >>> true
boolean res25 = jedis.vsetattr("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
System.out.println(res25); // >>> true
boolean res26 = jedis.vsetattr("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
System.out.println(res26); // >>> true
boolean res27 = jedis.vsetattr("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
System.out.println(res27); // >>> true
boolean res28 = jedis.vsetattr("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
System.out.println(res28); // >>> true
List<String> res29 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\""));
System.out.println(res29); // >>> ["pt:A", "pt:C", "pt:B"]
List<String> res30 = jedis.vsimByElement("points", "pt:A",
new VSimParams().filter(".size == \"large\" && .price > 20.00"));
System.out.println(res30); // >>> ["pt:C", "pt:B"]
boolean res31 = jedis.vadd("quantSetQ8", new float[] { 1.262185f, 1.958231f }, "quantElement",
new VAddParams().q8());
System.out.println(res31); // >>> true
List<Double> res32 = jedis.vemb("quantSetQ8", "quantElement");
System.out.println("Q8: " + res32);
// >>> Q8: [~1.264, ~1.958]
boolean res33 = jedis.vadd("quantSetNoQ", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().noQuant());
System.out.println(res33); // >>> true
List<Double> res34 = jedis.vemb("quantSetNoQ", "quantElement");
System.out.println("NOQUANT: " + res34);
// >>> NOQUANT: [~1.262185, ~1.958231]
boolean res35 = jedis.vadd("quantSetBin", new float[] { 1.262185f, 1.958231f },
"quantElement", new VAddParams().bin());
System.out.println(res35); // >>> true
List<Double> res36 = jedis.vemb("quantSetBin", "quantElement");
System.out.println("BIN: " + res36);
// >>> BIN: [1, 1]
float[] values = new float[300];
for (int i = 0; i < 300; i++)
values[i] = i / 299.0f;
boolean res37 = jedis.vadd("setNotReduced", values, "element");
System.out.println(res37); // >>> true
long res38 = jedis.vdim("setNotReduced");
System.out.println(res38); // >>> 300
boolean res39 = jedis.vadd("setReduced", values, "element", 100, new VAddParams());
System.out.println(res39); // >>> true
long res40 = jedis.vdim("setReduced");
System.out.println(res40); // >>> 100
jedis.close();
}
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import java.util.concurrent.CompletableFuture;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();
CompletableFuture<Boolean> addPointA = asyncCommands.vadd("points", "pt:A", 1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointB = asyncCommands.vadd("points", "pt:B", -1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointC = asyncCommands.vadd("points", "pt:C", -1.0, 1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointD = asyncCommands.vadd("points", "pt:D", 1.0, -1.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
CompletableFuture<Boolean> addPointE = asyncCommands.vadd("points", "pt:E", 1.0, 0.0).thenApply(result -> {
System.out.println(result); // >>> true
return result;
}).toCompletableFuture();
// Chain checkDataType after all vadd operations complete
CompletableFuture<Void> vaddOperations = CompletableFuture
.allOf(addPointA, addPointB, addPointC, addPointD, addPointE)
.thenCompose(ignored -> asyncCommands.type("points")).thenAccept(result -> {
System.out.println(result); // >>> vectorset
}).toCompletableFuture();
CompletableFuture<Void> getCardinality = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> getDimensions = asyncCommands.vdim("points").thenAccept(result -> {
System.out.println(result); // >>> 2
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingA = asyncCommands.vemb("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingB = asyncCommands.vemb("points", "pt:B").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingC = asyncCommands.vemb("points", "pt:C").thenAccept(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingD = asyncCommands.vemb("points", "pt:D").thenAccept(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
}).toCompletableFuture();
CompletableFuture<Void> getEmbeddingE = asyncCommands.vemb("points", "pt:E").thenAccept(result -> {
System.out.println(result); // >>> [1.0, 0.0]
}).toCompletableFuture();
CompletableFuture<Void> setAttributeA = asyncCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> getAttributeA = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
}).toCompletableFuture();
CompletableFuture<Void> clearAttributeA = asyncCommands.vsetattr("points", "pt:A", "").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> verifyAttributeCleared = asyncCommands.vgetattr("points", "pt:A").thenAccept(result -> {
System.out.println(result); // >>> null
}).toCompletableFuture();
CompletableFuture<Void> addTempPointF = asyncCommands.vadd("points", "pt:F", 0.0, 0.0).thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityBefore = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 6
}).toCompletableFuture();
CompletableFuture<Void> removePointF = asyncCommands.vrem("points", "pt:F").thenAccept(result -> {
System.out.println(result); // >>> true
}).toCompletableFuture();
CompletableFuture<Void> checkCardinalityAfter = asyncCommands.vcard("points").thenAccept(result -> {
System.out.println(result); // >>> 5
}).toCompletableFuture();
CompletableFuture<Void> basicSimilaritySearch = asyncCommands.vsim("points", 0.9, 0.1).thenAccept(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
}).toCompletableFuture();
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
CompletableFuture<Void> similaritySearchWithScore = asyncCommands.vsimWithScore("points", vsimArgs, "pt:A")
.thenAccept(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
}).toCompletableFuture();
CompletableFuture<Void> filteredSimilaritySearch = asyncCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}");
}).thenCompose(result -> {
System.out.println(result); // >>> true
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return asyncCommands.vsim("points", filterArgs, "pt:A");
}).thenCompose(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return asyncCommands.vsim("points", filterArgs2, "pt:A");
}).thenAccept(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).toCompletableFuture();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
CompletableFuture<Void> quantizationOperations = asyncCommands
.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetQ8", "quantElement");
}).thenCompose(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return asyncCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetNoQ", "quantElement");
}).thenCompose(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return asyncCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vemb("quantSetBin", "quantElement");
}).thenAccept(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).toCompletableFuture();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
CompletableFuture<Void> dimensionalityReductionOperations = asyncCommands.vadd("setNotReduced", "element", values)
.thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setNotReduced");
}).thenCompose(result -> {
System.out.println(result); // >>> 300
return asyncCommands.vadd("setReduced", 100, "element", values);
}).thenCompose(result -> {
System.out.println(result); // >>> true
return asyncCommands.vdim("setReduced");
}).thenAccept(result -> {
System.out.println(result); // >>> 100
}).toCompletableFuture();
// Wait for all async operations to complete
CompletableFuture.allOf(
// Vector addition operations (chained: parallel vadd + sequential checkDataType)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.vector.QuantizationType;
import reactor.core.publisher.Mono;
public class VectorSetExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
Mono<Boolean> addPointA = reactiveCommands.vadd("points", "pt:A", 1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointB = reactiveCommands.vadd("points", "pt:B", -1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointC = reactiveCommands.vadd("points", "pt:C", -1.0, 1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointD = reactiveCommands.vadd("points", "pt:D", 1.0, -1.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Boolean> addPointE = reactiveCommands.vadd("points", "pt:E", 1.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Void> vaddOperations = Mono.when(addPointA, addPointB, addPointC, addPointD, addPointE)
.then(reactiveCommands.type("points")).doOnNext(result -> {
System.out.println(result); // >>> vectorset
}).then();
Mono<Long> getCardinality = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<Long> getDimensions = reactiveCommands.vdim("points").doOnNext(result -> {
System.out.println(result); // >>> 2
});
Mono<java.util.List<Double>> getEmbeddingA = reactiveCommands.vemb("points", "pt:A").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingB = reactiveCommands.vemb("points", "pt:B").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingC = reactiveCommands.vemb("points", "pt:C").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [-0.9999999403953552, 0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingD = reactiveCommands.vemb("points", "pt:D").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [0.9999999403953552, -0.9999999403953552]
});
Mono<java.util.List<Double>> getEmbeddingE = reactiveCommands.vemb("points", "pt:E").collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [1.0, 0.0]
});
Mono<Boolean> setAttributeA = reactiveCommands
.vsetattr("points", "pt:A", "{\"name\": \"Point A\", \"description\": \"First point added\"}")
.doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> getAttributeA = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {"name": "Point A", "description": "First point added"}
});
Mono<Boolean> clearAttributeA = reactiveCommands.vsetattr("points", "pt:A", "").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<String> verifyAttributeCleared = reactiveCommands.vgetattr("points", "pt:A").doOnNext(result -> {
System.out.println(result); // >>> null
});
Mono<Boolean> addTempPointF = reactiveCommands.vadd("points", "pt:F", 0.0, 0.0).doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityBefore = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 6
});
Mono<Boolean> removePointF = reactiveCommands.vrem("points", "pt:F").doOnNext(result -> {
System.out.println(result); // >>> true
});
Mono<Long> checkCardinalityAfter = reactiveCommands.vcard("points").doOnNext(result -> {
System.out.println(result); // >>> 5
});
Mono<java.util.List<String>> basicSimilaritySearch = reactiveCommands.vsim("points", 0.9, 0.1).collectList()
.doOnNext(result -> {
System.out.println(result); // >>> [pt:E, pt:A, pt:D, pt:C, pt:B]
});
VSimArgs vsimArgs = new VSimArgs();
vsimArgs.count(4L);
Mono<java.util.Map<String, Double>> similaritySearchWithScore = reactiveCommands
.vsimWithScore("points", vsimArgs, "pt:A").doOnNext(result -> {
System.out.println(result); // >>> {pt:A=1.0, pt:E=0.8535534143447876, pt:D=0.5, pt:C=0.5}
});
Mono<Void> filteredSimilaritySearch = reactiveCommands
.vsetattr("points", "pt:A", "{\"size\": \"large\", \"price\": 18.99}").doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:B", "{\"size\": \"large\", \"price\": 35.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:C", "{\"size\": \"large\", \"price\": 25.99}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:D", "{\"size\": \"small\", \"price\": 21.00}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vsetattr("points", "pt:E", "{\"size\": \"small\", \"price\": 17.75}"))
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> {
// Return elements in order of distance from point A whose size attribute is large.
VSimArgs filterArgs = new VSimArgs();
filterArgs.filter(".size == \"large\"");
return reactiveCommands.vsim("points", filterArgs, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:A, pt:C, pt:B]
}).flatMap(result -> {
// Return elements in order of distance from point A whose size is large and price > 20.00.
VSimArgs filterArgs2 = new VSimArgs();
filterArgs2.filter(".size == \"large\" && .price > 20.00");
return reactiveCommands.vsim("points", filterArgs2, "pt:A").collectList();
}).doOnNext(result -> {
System.out.println(result); // >>> [pt:C, pt:B]
}).then();
VAddArgs q8Args = VAddArgs.Builder.quantizationType(QuantizationType.Q8);
Mono<Void> quantizationOperations = reactiveCommands.vadd("quantSetQ8", "quantElement", q8Args, 1.262185, 1.958231)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetQ8", "quantElement").collectList()).doOnNext(result -> {
System.out.println("Q8: " + result); // >>> Q8: [1.2643694877624512, 1.958230972290039]
}).flatMap(result -> {
VAddArgs noQuantArgs = VAddArgs.Builder.quantizationType(QuantizationType.NO_QUANTIZATION);
return reactiveCommands.vadd("quantSetNoQ", "quantElement", noQuantArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetNoQ", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("NOQUANT: " + result); // >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}).flatMap(result -> {
VAddArgs binArgs = VAddArgs.Builder.quantizationType(QuantizationType.BINARY);
return reactiveCommands.vadd("quantSetBin", "quantElement", binArgs, 1.262185, 1.958231);
}).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vemb("quantSetBin", "quantElement").collectList())
.doOnNext(result -> {
System.out.println("BIN: " + result); // >>> BIN: [1.0, 1.0]
}).then();
// Create a list of 300 arbitrary values.
Double[] values = new Double[300];
for (int i = 0; i < 300; i++) {
values[i] = (double) i / 299;
}
Mono<Void> dimensionalityReductionOperations = reactiveCommands.vadd("setNotReduced", "element", values)
.doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setNotReduced")).doOnNext(result -> {
System.out.println(result); // >>> 300
}).flatMap(result -> reactiveCommands.vadd("setReduced", 100, "element", values)).doOnNext(result -> {
System.out.println(result); // >>> true
}).flatMap(result -> reactiveCommands.vdim("setReduced")).doOnNext(result -> {
System.out.println(result); // >>> 100
}).then();
// Wait for all reactive operations to complete
Mono.when(
// Vector addition operations (chained sequentially)
vaddOperations,
// Cardinality and dimension operations
getCardinality, getDimensions,
// Vector embedding retrieval operations
getEmbeddingA, getEmbeddingB, getEmbeddingC, getEmbeddingD, getEmbeddingE,
// Attribute operations
setAttributeA, getAttributeA, clearAttributeA, verifyAttributeCleared,
// Vector removal operations
addTempPointF, checkCardinalityBefore, removePointF, checkCardinalityAfter,
// Similarity search operations
basicSimilaritySearch, similaritySearchWithScore, filteredSimilaritySearch,
// Advanced operations
quantizationOperations, dimensionalityReductionOperations).block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"sort"
"github.com/redis/go-redis/v9"
)
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()
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
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
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]
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)
}
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
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]
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}]
// 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]
}
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()
// 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]
}
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()
// 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
}
using StackExchange.Redis;
public class VectorSetTutorial
{
public void Run()
{
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = muxer.GetDatabase();
bool r1 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:A", new float[] { 1f, 1f }, null));
Console.WriteLine(r1); // >>> True
bool r2 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:B", new float[] { -1f, -1f }, null));
Console.WriteLine(r2); // >>> True
bool r3 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:C", new float[] { -1f, 1f }, null));
Console.WriteLine(r3); // >>> True
bool r4 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:D", new float[] { 1f, -1f }, null));
Console.WriteLine(r4); // >>> True
bool r5 = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:E", new float[] { 1f, 0f }, null));
Console.WriteLine(r5); // >>> True
long card = db.VectorSetLength("points");
Console.WriteLine(card); // >>> 5
int dim = db.VectorSetDimension("points");
Console.WriteLine(dim); // >>> 2
using (Lease<float>? eA = db.VectorSetGetApproximateVector("points", "pt:A"))
{
Span<float> a = eA!.Span;
Console.WriteLine($"[{a[0]}, {a[1]}]"); // >>> [0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eB = db.VectorSetGetApproximateVector("points", "pt:B"))
{
Span<float> b = eB!.Span;
Console.WriteLine($"[{b[0]}, {b[1]}]"); // >>> [-0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eC = db.VectorSetGetApproximateVector("points", "pt:C"))
{
Span<float> c = eC!.Span;
Console.WriteLine($"[{c[0]}, {c[1]}]"); // >>> [-0.9999999403953552, 0.9999999403953552]
}
using (Lease<float>? eD = db.VectorSetGetApproximateVector("points", "pt:D"))
{
Span<float> d = eD!.Span;
Console.WriteLine($"[{d[0]}, {d[1]}]"); // >>> [0.9999999403953552, -0.9999999403953552]
}
using (Lease<float>? eE = db.VectorSetGetApproximateVector("points", "pt:E"))
{
Span<float> e = eE!.Span;
Console.WriteLine($"[{e[0]}, {e[1]}]"); // >>> [1, 0]
}
string attrJson = "{\"name\":\"Point A\",\"description\":\"First point added\"}";
bool setAttr1 = db.VectorSetSetAttributesJson("points", "pt:A", attrJson);
Console.WriteLine(setAttr1); // >>> True
string? getAttr1 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr1); // >>> {"name":"Point A","description":"First point added"}
bool clearAttr = db.VectorSetSetAttributesJson("points", "pt:A", "");
Console.WriteLine(clearAttr); // >>> True
string? getAttr2 = db.VectorSetGetAttributesJson("points", "pt:A");
Console.WriteLine(getAttr2 is null ? "None" : getAttr2); // >>> None
bool addF = db.VectorSetAdd("points", VectorSetAddRequest.Member("pt:F", new float[] { 0f, 0f }, null));
Console.WriteLine(addF); // >>> True
long card1 = db.VectorSetLength("points");
Console.WriteLine(card1); // >>> 6
bool remF = db.VectorSetRemove("points", "pt:F");
Console.WriteLine(remF); // >>> True
long card2 = db.VectorSetLength("points");
Console.WriteLine(card2); // >>> 5
VectorSetSimilaritySearchRequest qBasic = VectorSetSimilaritySearchRequest.ByVector(new float[] { 0.9f, 0.1f });
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qBasic))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
string[] ordered = items.Select(x => (string?)x.Member).Where(s => s is not null).Select(s => s!).ToArray();
Console.WriteLine("[" + string.Join(", ", ordered.Select(s => $"'{s}'")) + "]");
// >>> ['pt:E', 'pt:A', 'pt:D', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qOpts = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qOpts.WithScores = true;
qOpts.Count = 4;
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qOpts))
{
VectorSetSimilaritySearchResult[] items = res!.Span.ToArray();
Dictionary<string, double> dict = items
.Select(i => new { Key = (string?)i.Member, i.Score })
.Where(x => x.Key is not null)
.ToDictionary(x => x.Key!, x => x.Score);
Console.WriteLine("{" + string.Join(", ", dict.Select(kv => $"'{kv.Key}': {kv.Value}")) + "}");
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
}
bool okA = db.VectorSetSetAttributesJson("points", "pt:A", "{\"size\":\"large\",\"price\":18.99}");
Console.WriteLine(okA); // >>> True
bool okB = db.VectorSetSetAttributesJson("points", "pt:B", "{\"size\":\"large\",\"price\":35.99}");
Console.WriteLine(okB); // >>> True
bool okC = db.VectorSetSetAttributesJson("points", "pt:C", "{\"size\":\"large\",\"price\":25.99}");
Console.WriteLine(okC); // >>> True
bool okD = db.VectorSetSetAttributesJson("points", "pt:D", "{\"size\":\"small\",\"price\":21.00}");
Console.WriteLine(okD); // >>> True
bool okE = db.VectorSetSetAttributesJson("points", "pt:E", "{\"size\":\"small\",\"price\":17.75}");
Console.WriteLine(okE); // >>> True
VectorSetSimilaritySearchRequest qFilt1 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt1.FilterExpression = ".size == \"large\"";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt1))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:A', 'pt:C', 'pt:B']
}
VectorSetSimilaritySearchRequest qFilt2 = VectorSetSimilaritySearchRequest.ByMember("pt:A");
qFilt2.FilterExpression = ".size == \"large\" && .price > 20.00";
using (Lease<VectorSetSimilaritySearchResult>? res = db.VectorSetSimilaritySearch("points", qFilt2))
{
string[] ids = res!.Span.ToArray()
.Select(i => (string?)i.Member)
.Where(s => s is not null)
.Select(s => s!)
.ToArray();
Console.WriteLine("[" + string.Join(", ", ids.Select(s => $"'{s}'")) + "]");
// >>> ['pt:C', 'pt:B']
}
VectorSetAddRequest addInt8 = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addInt8.Quantization = VectorSetQuantization.Int8;
bool q8Added = db.VectorSetAdd("quantSetQ8", addInt8);
Console.WriteLine(q8Added); // >>> True
using (Lease<float>? eInt8 = db.VectorSetGetApproximateVector("quantSetQ8", "quantElement"))
{
Span<float> v = eInt8!.Span;
Console.WriteLine($"Q8: [{v[0]}, {v[1]}]");
// >>> Q8: [1.2643694877624512, 1.958230972290039]
}
VectorSetAddRequest addNone = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addNone.Quantization = VectorSetQuantization.None;
bool noQuantAdded = db.VectorSetAdd("quantSetNoQ", addNone);
Console.WriteLine(noQuantAdded); // >>> True
using (Lease<float>? eNone = db.VectorSetGetApproximateVector("quantSetNoQ", "quantElement"))
{
Span<float> v = eNone!.Span;
Console.WriteLine($"NOQUANT: [{v[0]}, {v[1]}]");
// >>> NOQUANT: [1.262184977531433, 1.958230972290039]
}
VectorSetAddRequest addBinary = VectorSetAddRequest.Member("quantElement", new float[] { 1.262185f, 1.958231f }, null);
addBinary.Quantization = VectorSetQuantization.Binary;
bool binAdded = db.VectorSetAdd("quantSetBin", addBinary);
Console.WriteLine(binAdded); // >>> True
using (Lease<float>? eBinary = db.VectorSetGetApproximateVector("quantSetBin", "quantElement"))
{
Span<float> v = eBinary!.Span;
Console.WriteLine($"BIN: [{v[0]}, {v[1]}]");
// >>> BIN: [1, 1]
}
float[] values = Enumerable.Range(0, 300).Select(x => (float)(x / 299.0)).ToArray();
bool addedNotReduced = db.VectorSetAdd("setNotReduced", VectorSetAddRequest.Member("element", values, null));
Console.WriteLine(addedNotReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setNotReduced")); // >>> 300
VectorSetAddRequest addReduced = VectorSetAddRequest.Member("element", values, null);
addReduced.ReducedDimensions = 100;
bool addedReduced = db.VectorSetAdd("setReduced", addReduced);
Console.WriteLine(addedReduced); // >>> True
Console.WriteLine(db.VectorSetDimension("setReduced")); // >>> 100
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtVecSetsTest
{
public function testDtVecSet() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->vadd('points', [1.0, 1.0], 'pt:A');
echo $res1 . PHP_EOL;
// >>> 1
$res2 = $r->vadd('points', [-1.0, -1.0], 'pt:B');
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->vadd('points', [-1.0, 1.0], 'pt:C');
echo $res3 . PHP_EOL;
// >>> 1
$res4 = $r->vadd('points', [1.0, -1.0], 'pt:D');
echo $res4 . PHP_EOL;
// >>> 1
$res5 = $r->vadd('points', [1.0, 0.0], 'pt:E');
echo $res5 . PHP_EOL;
// >>> 1
$res6 = $r->type('points');
echo $res6 . PHP_EOL;
// >>> vectorset
$res7 = $r->vcard('points');
echo $res7 . PHP_EOL;
// >>> 5
$res8 = $r->vdim('points');
echo $res8 . PHP_EOL;
// >>> 2
$res9 = $r->vemb('points', 'pt:A');
echo json_encode($res9) . PHP_EOL;
// >>> [0.9999999403953552, 0.9999999403953552]
$res10 = $r->vemb('points', 'pt:B');
echo json_encode($res10) . PHP_EOL;
// >>> [-0.9999999403953552, -0.9999999403953552]
$res11 = $r->vemb('points', 'pt:C');
echo json_encode($res11) . PHP_EOL;
// >>> [-0.9999999403953552, 0.9999999403953552]
$res12 = $r->vemb('points', 'pt:D');
echo json_encode($res12) . PHP_EOL;
// >>> [0.9999999403953552, -0.9999999403953552]
$res13 = $r->vemb('points', 'pt:E');
echo json_encode($res13) . PHP_EOL;
// >>> [1,0]
$res14 = $r->vsetattr('points', 'pt:A', '{
"name": "Point A",
"description": "First point added"
}');
echo $res14 . PHP_EOL;
// >>> 1
$res15 = $r->vgetattr('points', 'pt:A');
echo json_encode($res15) . PHP_EOL;
// >>> {"name":"Point A","description":"First point added"}
$res16 = $r->vsetattr('points', 'pt:A', '');
echo $res16 . PHP_EOL;
// >>> 1
$res17 = $r->vgetattr('points', 'pt:A');
echo json_encode($res17) . PHP_EOL;
// >>> null
$res18 = $r->vadd('points', [0, 0], 'pt:F');
echo $res18 . PHP_EOL;
// >>> 1
$res19 = $r->vcard('points');
echo $res19 . PHP_EOL;
// >>> 6
$res20 = $r->vrem('points', 'pt:F');
echo $res20 . PHP_EOL;
// >>> 1
$res21 = $r->vcard('points');
echo $res21 . PHP_EOL;
// >>> 5
$res22 = $r->vsim('points', [0.9, 0.1]);
echo json_encode($res22) . PHP_EOL;
// >>> ["pt:E","pt:A","pt:D","pt:C","pt:B"]
// Returns an array of elements with their scores:
// ['pt:A' => 1.0, 'pt:E' => 0.8535534143447876,...
$res23 = $r->vsim(
'points', 'pt:A', true,true, 4,
);
echo json_encode($res23) . PHP_EOL;
// >>> {'pt:A': 1.0, 'pt:E': 0.8535534143447876, 'pt:D': 0.5, 'pt:C': 0.5}
$res24 = $r->vsetattr('points', 'pt:A', [
'size' => 'large',
'price' => 18.99
]);
echo $res24 . PHP_EOL;
// >>> 1
$res25 = $r->vsetattr('points', 'pt:B', [
'size' => 'large',
'price' => 35.99
]);
echo $res25 . PHP_EOL;
// >>> 1
$res26 = $r->vsetattr('points', 'pt:C', [
'size' => 'large',
'price' => 25.99
]);
echo $res26 . PHP_EOL;
// >>> 1
$res27 = $r->vsetattr('points', 'pt:D', [
'size' => 'small',
'price' => 21.00
]);
echo $res27 . PHP_EOL;
// >>> 1
$res28 = $r->vsetattr('points', 'pt:E', [
'size' => 'small',
'price' => 17.75
]);
echo $res28 . PHP_EOL;
// >>> 1
// Return elements in order of distance from point A whose
// `size` attribute is `large`.
$res29 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large"'
);
echo json_encode($res29) . PHP_EOL;
// >>> ["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 = $r->vsim(
'points', 'pt:A',true, null, null, null, null,
'.size == "large" && .price > 20.00'
);
echo json_encode($res30) . PHP_EOL;
// >>> ["pt:C","pt:B"]
$res31 = $r->vadd('quantSetQ8', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_Q8
);
echo $res31 . PHP_EOL;
// >>> 1
$res32 = $r->vemb('quantSetQ8', 'quantElement');
echo json_encode($res32) . PHP_EOL;
// >>> [1.2643694877624512, 1.958230972290039]
$res33 = $r->vadd('quantSetNoQ', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_NOQUANT
);
echo $res33 . PHP_EOL;
// >>> 1
$res34 = $r->vemb('quantSetNoQ', 'quantElement');
echo json_encode($res34) . PHP_EOL;
// >>> [1.262184977531433, 1.958230972290039]
$res35 = $r->vadd('quantSetBin', [1.262185, 1.958231], 'quantElement', null, false,
Predis\Command\Redis\VADD::QUANT_BIN
);
echo $res35 . PHP_EOL;
// >>> 1
$res36 = $r->vemb('quantSetBin', 'quantElement');
echo json_encode($res36) . PHP_EOL;
// >>> [1, 1]
$values = array();
for ($i = 0; $i < 300; $i++) {
$values[] = $i / 299.0;
}
$res37 = $r->vadd('setNotReduced', $values, 'element');
echo $res37 . PHP_EOL;
// >>> 1
$res38 = $r->vdim('setNotReduced');
echo $res38 . PHP_EOL;
// >>> 300
$res39 = $r->vadd('setReduced', $values, 'element', 100);
echo $res39 . PHP_EOL;
// >>> 1
$res40 = $r->vdim('setReduced');
echo $res40 . PHP_EOL;
// >>> 100
}
}
More information
See the other pages in this section to learn more about the features and performance parameters of vector sets.