Skip to content

Commit 7f33826

Browse files
authored
Updating recipes for Spring Boot: Spring AI and Redis OM Spring (#100)
1 parent 285c0c6 commit 7f33826

File tree

13 files changed

+462
-361
lines changed

13 files changed

+462
-361
lines changed

java-recipes/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ Notebooks require a Jupyter Notebook environment to run. Check out the [Setup In
3232

3333
## Applications
3434

35-
| Application | Description |
36-
|-----------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
37-
| [applications/vector-similarity-search/spring_boot](./applications/vector-similarity-search/spring_boot_redis_om_spring.md) | Demonstrates building a vector similarity search application using Spring Boot and Redis OM Spring |
35+
| Application | Description |
36+
|-------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
37+
| [applications/vector-similarity-search/redis-om-spring](./applications/vector-similarity-search/redis-om-spring/spring_boot_redis_om_spring.md) | Demonstrates building a vector similarity search application using Spring Boot and Redis OM Spring |
38+
| [applications/vector-similarity-search/spring-ai](./applications/vector-similarity-search/spring-ai/spring_boot_spring_ai.md) | Demonstrates building a vector similarity search application using Spring Boot and Spring AI |
3839

3940

4041
## Example Notebooks & Applications
163 KB
Loading
168 KB
Loading
973 KB
Loading
349 KB
Loading
1.02 MB
Loading
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# Vector Search with Redis OM Spring (SpringBoot)
2+
3+
Vector similarity search (also known as semantic search) is a powerful technique that allows you to find items based on their semantic meaning rather than exact keyword matches. Redis Query Engine supports vector similarity search through its vector indexing capabilities, enabling you to implement semantic search applications with high performance and low latency.
4+
5+
This demo showcases how to implement vector similarity search using Redis OM Spring, a library that simplifies working with Redis data models and the Redis Query Engine.
6+
7+
## Learning resources:
8+
9+
- Article: [Semantic Search with Spring Boot & Redis](https://raphaeldelio.com/2025/04/29/semantic-search-with-spring-boot-redis/)
10+
- Video: [Autocomplete in Spring with Redis](https://www.youtube.com/watch?v=rjaR1PR5gVk)
11+
- Video: [What is an embedding model?](https://youtu.be/0U1S0WSsPuE)
12+
- Video: [Exact vs Approximate Nearest Neighbors - What's the difference?](https://youtu.be/9NvO-VdjY80)
13+
- Video: [What is semantic search?](https://youtu.be/o3XN4dImESE)
14+
- Video: [What is a vector database?](https://youtu.be/Yhv19le0sBw)
15+
16+
17+
## Repository
18+
19+
The repository for this demo can be found [here](https://github.com/redis-developer/redis-springboot-resources/tree/main/search/vector-search)
20+
21+
## Requirements
22+
23+
To run this demo, you’ll need the following installed on your system:
24+
- Docker – [Install Docker](https://docs.docker.com/get-docker/)
25+
- Docker Compose – Included with Docker Desktop or available via CLI installation guide
26+
27+
## Running the demo
28+
29+
The easiest way to run the demo is with Docker Compose, which sets up all required services in one command.
30+
31+
### Step 1: Clone the repository
32+
33+
If you haven’t already:
34+
35+
```bash
36+
git clone https://github.com/redis-developer/redis-springboot-recipes.git
37+
cd redis-springboot-recipes/search/full-text-search-and-autocomplete
38+
```
39+
40+
### Step 2: Start the services
41+
42+
```bash
43+
docker compose up --build
44+
```
45+
46+
This will start:
47+
48+
- redis: for storing documents
49+
- redis-insight: a UI to explore the Redis data
50+
- vector-search-app: the Spring Boot app that implements vector search
51+
52+
## Using the demo
53+
54+
When all of your services are up and running. Go to `localhost:8080` to access the demo.
55+
56+
If you search using the extract box, the system will perform semantic search and find items on the database that are semantically similar to your query:
57+
58+
![Screenshot of a movie search app using vector similarity search. The user searches for “movie about a clownfish who searches for his son.” The top result is Finding Nemo, with a similarity score of 0.505, followed by Big Fish and Swordfish. Each result includes a poster, title, year, cast, genres, and description snippet.](readme-assets/vector-search.png)
59+
60+
You can also apply filters for pre-filtering the results before applying semantic search:
61+
62+
![Screenshot of a movie search app using vector similarity search with filters applied: cast = Albert Brooks, genre = animated. The query is “movie about a clownfish who searches for his son.” Results include Finding Nemo, Finding Nemo 3D, and Finding Dory, each with similarity scores, posters, cast, genres, and descriptions.](readme-assets/pre-filtered-vector-search.png)
63+
64+
This demo also supports autocompletion of the title:
65+
66+
![Close-up screenshot of a movie search app’s autocomplete feature. The user types “Finding” in the “Movie Title” field, triggering a dropdown with suggestions like Finding You, Finding Nemo, Finding Dory, Finding Bliss, and Finding Amanda. Autocomplete response time is shown as 8 ms.](readme-assets/autocomplete.png)
67+
68+
### Redis Insight
69+
70+
RedisInsight is a graphical tool developed by Redis to help developers and administrators interact with and manage Redis databases more efficiently. It provides a visual interface for exploring keys, running commands, analyzing memory usage, and monitoring performance metrics in real-time. RedisInsight supports features like full-text search, time series, streams, and vector data structures, making it especially useful for working with more advanced Redis use cases. With its intuitive UI, it simplifies debugging, optimizing queries, and understanding data patterns without requiring deep familiarity with the Redis CLI.
71+
72+
The Docker Compose file will also spin up an instance of Redis Insight. We can access it by going to `localhost:5540`:
73+
74+
If we go to Redis Insight, we will be able to see the data stored in Redis:
75+
76+
![Screenshot of RedisInsight showing 10,000 JSON movie documents in the com.redis.vectorsearch.domain.Movie namespace. The selected document is for Star Trek III: The Search for Spock, displaying fields like title, year, genres, extract, and a thumbnail URL. The embeddedExtract vector field is also included.](readme-assets/redis-insight.png)
77+
78+
And if run the command `FT.INFO 'com.redis.fulltextsearchandautocomplete.domain.MovieIdx'`, we'll be able to see the schema that was created for indexing our documents efficiently:
79+
80+
![Screenshot of RedisInsight displaying the schema of the MovieIdx vector search index. The index is built on JSON documents and includes fields like title, year, cast, genres, embeddedExtract (VECTOR), and id. The vector field uses the HNSW algorithm with FLOAT32 data type, 384 dimensions, COSINE distance metric, M=16, and EF_CONSTRUCTION=200.](readme-assets/index-redis-insight.png)
81+
82+
## How It Is Implemented
83+
84+
The application uses Redis OM Spring to vectorize documents and perform vector similarity search. Here's how it works:
85+
86+
### Defining Vector Fields with Redis OM Spring Annotations
87+
88+
Documents are defined as Java classes with Redis OM Spring annotations that specify how they should be vectorized and indexed:
89+
90+
```java
91+
@Document
92+
public class Movie {
93+
// Other fields...
94+
95+
@Vectorize(
96+
destination = "embeddedExtract",
97+
embeddingType = EmbeddingType.SENTENCE
98+
)
99+
private String extract;
100+
101+
@Indexed(
102+
schemaFieldType = SchemaFieldType.VECTOR,
103+
algorithm = VectorField.VectorAlgorithm.HNSW,
104+
type = VectorType.FLOAT32,
105+
dimension = 384,
106+
distanceMetric = DistanceMetric.COSINE,
107+
initialCapacity = 10
108+
)
109+
private float[] embeddedExtract;
110+
111+
// Getters and setters...
112+
}
113+
```
114+
115+
Let's break down the annotations:
116+
117+
- `@Vectorize`: Automatically generates vector embeddings for the text field
118+
- `destination`: Specifies the field where the embedding will be stored
119+
- `embeddingType`: Defines the granularity of the embedding (SENTENCE in this case)
120+
121+
- `@Indexed` with vector parameters:
122+
- `schemaFieldType = SchemaFieldType.VECTOR`: Marks this as a vector field
123+
- `algorithm = VectorField.VectorAlgorithm.HNSW`: Uses the Hierarchical Navigable Small World algorithm for efficient approximate nearest neighbor search
124+
- `type = VectorType.FLOAT32`: Specifies the vector data type
125+
- `dimension = 384`: Sets the vector dimension (must match the number of dimensions output by the embedding model)
126+
- `distanceMetric = DistanceMetric.COSINE`: Uses cosine similarity for distance calculation
127+
128+
### Storing and Vectorizing Documents
129+
130+
When documents are saved to Redis using the repository, Redis OM Spring automatically generates vector embeddings:
131+
132+
```java
133+
public void loadAndSaveMovies(String filePath) throws Exception {
134+
// Load movies from JSON file
135+
List<Movie> movies = objectMapper.readValue(is, new TypeReference<>() {});
136+
137+
// Save movies in batches
138+
int batchSize = 500;
139+
for (int i = 0; i < unprocessedMovies.size(); i += batchSize) {
140+
int end = Math.min(i + batchSize, unprocessedMovies.size());
141+
List<Movie> batch = unprocessedMovies.subList(i, end);
142+
movieRepository.saveAll(batch);
143+
}
144+
}
145+
```
146+
147+
When `movieRepository.saveAll(batch)` is called:
148+
1. Redis OM Spring generates vector embeddings for the `extract` field
149+
2. The embeddings are stored in the `embeddedExtract` field
150+
3. The documents are saved to Redis with their vector embeddings
151+
4. Redis creates a vector index for efficient similarity search
152+
153+
### Performing Vector Similarity Search
154+
155+
Vector similarity search is implemented using Redis OM Spring's EntityStream API:
156+
157+
```java
158+
public Map<String, Object> search(
159+
String title,
160+
String extract,
161+
List<String> actors,
162+
Integer year,
163+
List<String> genres,
164+
Integer numberOfNearestNeighbors
165+
) {
166+
SearchStream<Movie> stream = entityStream.of(Movie.class);
167+
168+
if (extract != null) {
169+
// Convert search query to vector embedding
170+
float[] embeddedQuery = embedder.getTextEmbeddingsAsFloats(List.of(extract), Movie$.EXTRACT).getFirst();
171+
172+
// Perform KNN search with the embedded query
173+
stream = stream.filter(Movie$.EMBEDDED_EXTRACT.knn(numberOfNearestNeighbors, embeddedQuery))
174+
.sorted(Movie$._EMBEDDED_EXTRACT_SCORE);
175+
}
176+
177+
// Apply additional filters
178+
List<Pair<Movie, Double>> matchedMovies = stream
179+
.filter(Movie$.TITLE.containing(title))
180+
.filter(Movie$.CAST.eq(actors))
181+
.filter(Movie$.YEAR.eq(year))
182+
.filter(Movie$.GENRES.eq(genres))
183+
.map(Fields.of(Movie$._THIS, Movie$._EMBEDDED_EXTRACT_SCORE))
184+
.collect(Collectors.toList());
185+
186+
return result;
187+
}
188+
```
189+
190+
This method:
191+
1. Converts the search query text into a vector embedding using the same embedding model
192+
2. Performs a K-Nearest Neighbors (KNN) search to find the most similar vectors
193+
3. Applies additional filters to narrow down the results (pre-filtering)
194+
4. Returns the matched movies along with their similarity scores
195+
196+
### Combining Vector Search with Autocomplete
197+
198+
The application also supports autocomplete functionality alongside vector search:
199+
200+
```java
201+
public interface MovieRepository extends RedisDocumentRepository<Movie, String> {
202+
List<Suggestion> autoCompleteTitle(String title, AutoCompleteOptions options);
203+
}
204+
```
205+
206+
The `autoCompleteTitle` method is automatically implemented by Redis OM Spring based on the `@AutoComplete` annotation on the `title` field in the Movie class.
207+
208+
### How Redis Indexes the Vectors
209+
210+
When the application starts, Redis OM Spring creates a vector index in Redis based on the annotations:
211+
212+
```
213+
FT.CREATE idx:com.redis.vectorsearch.domain.Movie ON JSON PREFIX 1 com.redis.vectorsearch.domain.Movie: SCHEMA
214+
$.title AS title TEXT SORTABLE
215+
$.year AS year NUMERIC SORTABLE
216+
$.cast AS cast TAG
217+
$.genres AS genres TAG
218+
$.embeddedExtract AS embeddedExtract VECTOR HNSW 6 TYPE FLOAT32 DIM 384 DISTANCE_METRIC COSINE INITIAL_CAP 10
219+
```
220+
221+
This index enables efficient vector similarity search with the following features:
222+
- HNSW algorithm for approximate nearest neighbor search
223+
- 384-dimensional FLOAT32 vectors
224+
- Cosine similarity as the distance metric
225+
- Additional text and tag fields for filtering
226+
227+
This approach allows for high-performance semantic search operations, even with large datasets, by leveraging Redis's in-memory data structures and the Redis Query Engine's vector search capabilities.
168 KB
Loading
973 KB
Loading
349 KB
Loading

0 commit comments

Comments
 (0)