Skip to content

Commit 1a79e4b

Browse files
DOC-5552 added Jedis vector set embedding examples
1 parent d6e4711 commit 1a79e4b

File tree

2 files changed

+367
-168
lines changed

2 files changed

+367
-168
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
- rs
8+
- rc
9+
- oss
10+
- kubernetes
11+
- clients
12+
description: Index and query embeddings with Redis vector sets
13+
linkTitle: Vector set embeddings
14+
title: Vector set embeddings
15+
weight: 4
16+
bannerText: Vector set is a new data type that is currently in preview and may be subject to change.
17+
bannerChildren: true
18+
---
19+
20+
A Redis [vector set]({{< relref "/develop/data-types/vector-sets" >}}) lets
21+
you store a set of unique keys, each with its own associated vector.
22+
You can then retrieve keys from the set according to the similarity between
23+
their stored vectors and a query vector that you specify.
24+
25+
You can use vector sets to store any type of numeric vector but they are
26+
particularly optimized to work with text embedding vectors (see
27+
[Redis for AI]({{< relref "/develop/ai" >}}) to learn more about text
28+
embeddings). The example below shows how to generate vector embeddings and then
29+
store and retrieve them using a vector set with `Jedis`.
30+
31+
## Initialize
32+
33+
If you are using [Maven](https://maven.apache.org/), add the following
34+
dependencies to your `pom.xml` file
35+
(note that you need `Jedis` v6.2.0 or later to use vector sets):
36+
37+
```xml
38+
<dependency>
39+
<groupId>redis.clients</groupId>
40+
<artifactId>jedis</artifactId>
41+
<version>6.2.0</version>
42+
</dependency>
43+
44+
<dependency>
45+
<groupId>ai.djl.huggingface</groupId>
46+
<artifactId>tokenizers</artifactId>
47+
<version>0.33.0</version>
48+
</dependency>
49+
50+
<dependency>
51+
<groupId>ai.djl.pytorch</groupId>
52+
<artifactId>pytorch-model-zoo</artifactId>
53+
<version>0.33.0</version>
54+
</dependency>
55+
56+
<dependency>
57+
<groupId>ai.djl</groupId>
58+
<artifactId>api</artifactId>
59+
<version>0.33.0</version>
60+
</dependency>
61+
```
62+
63+
If you are using [Gradle](https://gradle.org/), add the following
64+
dependencies to your `build.gradle` file:
65+
66+
```bash
67+
compileOnly 'redis.clients:jedis:6.2.0'
68+
compileOnly 'ai.djl.huggingface:tokenizers:0.33.0'
69+
compileOnly 'ai.djl.pytorch:pytorch-model-zoo:0.33.0'
70+
compileOnly 'ai.djl:api:0.33.0'
71+
```
72+
73+
In a new Java file, import the required classes:
74+
75+
{{< clients-example set="home_vecsets" step="import" lang_filter="Java-Sync" >}}
76+
{{< /clients-example >}}
77+
78+
The imports include the classes required to generate embeddings from text.
79+
This example uses an instance of the `Predictor` class with the
80+
[`all-MiniLM-L6-v2`](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)
81+
model for the embeddings. This model generates vectors with 384 dimensions, regardless
82+
of the length of the input text, but note that the input is truncated to 256
83+
tokens (see
84+
[Word piece tokenization](https://huggingface.co/learn/nlp-course/en/chapter6/6)
85+
at the [Hugging Face](https://huggingface.co/) docs to learn more about the way tokens
86+
are related to the original text).
87+
88+
{{< clients-example set="home_vecsets" step="model" lang_filter="Java-Sync" >}}
89+
{{< /clients-example >}}
90+
91+
## Create the data
92+
93+
The example data is contained in a `List<Person>` object with some brief
94+
descriptions of famous people.
95+
96+
{{< clients-example set="home_vecsets" step="data" lang_filter="Java-Sync" >}}
97+
{{< /clients-example >}}
98+
99+
## Add the data to a vector set
100+
101+
The code below connects to Redis, then iterates through all the items in the `people` list,
102+
generates embeddings for each person's description, and then
103+
adds the appropriate elements to a vector set called `famousPeople`.
104+
Note that the `predict()` call is in a `try`/`catch` block because it can throw
105+
exceptions if it can't download the embedding model (you should add code to handle
106+
the exceptions for production).
107+
108+
The call to `vadd()` also adds the `born` and `died` values from the
109+
original `people` list as attribute data. You can access this during a query
110+
or by using the [`vgetattr()`]({{< relref "/commands/vgetattr" >}}) method.
111+
112+
{{< clients-example set="home_vecsets" step="add_data" lang_filter="Java-Sync" >}}
113+
{{< /clients-example >}}
114+
115+
## Query the vector set
116+
117+
You can now query the data in the set. The basic approach is to use the
118+
`predict()` method to generate another embedding vector for the query text.
119+
(This is the same method used to add the elements to the set.) Then, pass
120+
the query vector to [`vsim()`]({{< relref "/commands/vsim" >}}) to return elements
121+
of the set, ranked in order of similarity to the query.
122+
123+
Start with a simple query for "actors":
124+
125+
{{< clients-example set="home_vecsets" step="basic_query" lang_filter="Java-Sync" >}}
126+
{{< /clients-example >}}
127+
128+
This returns the following list of elements (formatted slightly for clarity):
129+
130+
```
131+
['Masako Natsume', 'Chaim Topol', 'Linus Pauling',
132+
'Marie Fredriksson', 'Maryam Mirzakhani', 'Marie Curie',
133+
'Freddie Mercury', 'Paul Erdos']
134+
```
135+
136+
The first two people in the list are the two actors, as expected, but none of the
137+
people from Linus Pauling onward was especially well-known for acting (and there certainly
138+
isn't any information about that in the short description text).
139+
As it stands, the search attempts to rank all the elements in the set, based
140+
on the information contained in the embedding model.
141+
You can use the `count` parameter of `vsim()` to limit the list of elements
142+
to just the most relevant few items:
143+
144+
{{< clients-example set="home_vecsets" step="limited_query" lang_filter="Java-Sync" >}}
145+
{{< /clients-example >}}
146+
147+
The reason for using text embeddings rather than simple text search
148+
is that the embeddings represent semantic information. This allows a query
149+
to find elements with a similar meaning even if the text is
150+
different. For example, the word "entertainer" doesn't appear in any of the
151+
descriptions, but if you use it as a query, the actors and musicians are ranked
152+
highest in the results list:
153+
154+
{{< clients-example set="home_vecsets" step="entertainer_query" lang_filter="Java-Async,Java-Reactive" >}}
155+
{{< /clients-example >}}
156+
157+
Similarly, if you use "science" as a query, you get the following results:
158+
159+
```
160+
['Marie Curie', 'Linus Pauling', 'Maryam Mirzakhani',
161+
'Paul Erdos', 'Marie Fredriksson', 'Freddie Mercury', 'Masako Natsume',
162+
'Chaim Topol']
163+
```
164+
165+
The scientists are ranked highest, followed by the
166+
mathematicians. This ranking seems reasonable given the connection between mathematics and science.
167+
168+
You can also use
169+
[filter expressions]({{< relref "/develop/data-types/vector-sets/filtered-search" >}})
170+
with `vsim()` to restrict the search further. For example,
171+
repeat the "science" query, but this time limit the results to people
172+
who died before the year 2000:
173+
174+
{{< clients-example set="home_vecsets" step="filtered_query" lang_filter="Java-Sync" >}}
175+
{{< /clients-example >}}
176+
177+
Note that the boolean filter expression is applied to items in the list
178+
before the vector distance calculation is performed. Items that don't
179+
pass the filter test are removed from the results completely, rather
180+
than just reduced in rank. This can help to improve the performance of the
181+
search because there is no need to calculate the vector distance for
182+
elements that have already been filtered out of the search.
183+
184+
## More information
185+
186+
See the [vector sets]({{< relref "/develop/data-types/vector-sets" >}})
187+
docs for more information and code examples. See the
188+
[Redis for AI]({{< relref "/develop/ai" >}}) section for more details
189+
about text embeddings and other AI techniques you can use with Redis.
190+
191+
You may also be interested in
192+
[vector search]({{< relref "/develop/clients/jedis/vecsearch" >}}).
193+
This is a feature of the
194+
[Redis query engine]({{< relref "/develop/ai/search-and-query" >}})
195+
that lets you retrieve
196+
[JSON]({{< relref "/develop/data-types/json" >}}) and
197+
[hash]({{< relref "/develop/data-types/hashes" >}}) documents based on
198+
vector data stored in their fields.

0 commit comments

Comments
 (0)