The Simple Vector Store
provided by Spring AI
is an in-memory
implementation of the VectorStore Interface
. it's good for learning purposes but doesn't have persistence capability
, hence all the Embedding
will be lost once the application restarts. The Spring Ai Redis Vector Store
is one of the Persistant Vector Databases
supported by Spring AI to persist data.
The Spring Ai Redis Vector Store
is the Redis-based vector store
implementation of VectorStore interface
. The Spring Ai Redis Vector Store
stores vector embeddings
and metadata
into Redis JSON
documents, and for searching It uses RediSearch
for creating and querying vector embeddings
for similarity indexes
. The Spring Ai Redis Vector Store
provides full database capabilities
such as managing data, querying vector data, adding, deleting, and performing similarity searches on documents. The Spring Ai Redis Vector Store
supports vector algorithms (e.g., FLAT, HNSW) for efficient similarity searches
.
package com.example.springai.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class SpringAiController {
private final ChatClient chatClient;
@Autowired
private VectorStore redisVectorStore;
public SpringAiController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/redisVectorStore")
public String redisVectorStore(@RequestParam(value = "question", defaultValue = "What is Spring Framework?") String question) {
ChatResponse response = chatClient.prompt()
.advisors(new QuestionAnswerAdvisor(redisVectorStore))
.user(question)
.call()
.chatResponse();
return response.getResult().getOutput().getContent();
}
@GetMapping("/redisVectorStoreSimilaritySearch")
public List<Document> redisVectorStoreSimilaritySearch(@RequestParam(value = "question", defaultValue = "What is Spring Framework?") String question) {
List<Document> results = redisVectorStore.similaritySearch(SearchRequest.builder()
.query(question)
.topK(5)
.similarityThresholdAll()
.build());
return results;
}
}
package com.example.springai;
import org.springframework.ai.reader.ExtractedTextFormatter;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.reader.pdf.config.PdfDocumentReaderConfig;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
@SpringBootApplication
public class SpringAiApplication {
@Value("classpath:/docs/spring-faq.pdf")
private Resource pdfResource;
@Autowired
private VectorStore vectorStore;
public static void main(String[] args) {
SpringApplication.run(SpringAiApplication.class, args);
}
@Bean
VectorStore redisVectorStore() {
System.out.println("SpringAiApplication.redisVectorStore");
PagePdfDocumentReader pdfReader = new PagePdfDocumentReader(pdfResource, PdfDocumentReaderConfig.builder()
.withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
.withNumberOfBottomTextLinesToDelete(3)
.withNumberOfTopPagesToSkipBeforeDelete(1)
.build())
.withPagesPerDocument(1)
.build());
var tokenTextSplitter = new TokenTextSplitter();
this.vectorStore.accept(tokenTextSplitter.apply(pdfReader.get()));
return vectorStore;
}
}
spring.application.name=SpringAi
spring.docker.compose.lifecycle-management=start-only
spring.threads.virtual.enabled=true
spring.ai.vectorstore.redis.uri=redis://localhost:6379
spring.ai.vectorstore.redis.index=redis-index
spring.ai.vectorstore.redis.prefix=redis-prefix
spring.ai.vectorstore.redis.initialize-schema=true
# The default Ollama Model in Spring Ai is mistral, but it can be changed by setting the below property. make sure to download the same model in entrypoint.sh file
#spring.ai.ollama.chat.options.model=llama3.1
spring.ai.ollama.embedding.model=mistral
# If running the Ollama Docker Instance separately, then set this property
spring.docker.compose.enabled=false
services:
ollama-model:
image: ollama/ollama:latest
container_name: ollama_container
ports:
- 11434:11434/tcp
healthcheck:
test: ollama --version || exit 1
command: serve
volumes:
- ./ollama/ollama:/root/.ollama
- ./entrypoint.sh:/entrypoint.sh
pull_policy: missing
tty: true
restart: no
entrypoint: [ "/usr/bin/bash", "/entrypoint.sh" ]
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open_webui_container
environment:
WEBUI_AUTH: false
ports:
- "8081:8080"
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- open-webui:/app/backend/data
restart: no
redis:
image: redislabs/redismod
container_name: redislabs_container
restart: always
ports:
- "6379:6379"
# in redis-insight ui, add host name as redis
redis-insight:
image: redis/redisinsight:latest
container_name: redis_insight_container
restart: always
ports:
- '5540:5540'
volumes:
- redisinsight_db:/db
volumes:
open-webui:
redisinsight_db:
#!/bin/bash
# Start Ollama in the background.
/bin/ollama serve &
# Record Process ID.
pid=$!
# Pause for Ollama to start.
sleep 5
# The default Ollama Model in Spring Ai is mistral, but it can be changed in the applications property file. Make sure to download the same Model here
echo "🔴 Retrieve LLAMA3 model..."
ollama pull mistral
echo "🟢 Done!"
# Wait for the Ollama process to finish.
wait $pid
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/>
</parent>
<groupId>com.example.springai</groupId>
<artifactId>redis-vector-store</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Redis Vector Store</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-redis-store-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pdf-document-reader</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.springai.SpringAiApplication</mainClass>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
</project>
Open http://localhost:5540/
to log in to Redis Insight
, add the hostname as Redis
, and leave the username and password blank.
Run the curl to see the Spring Ai Redis Vector Store
curl --location 'localhost:8080/redisVectorStore'
curl --location 'localhost:8080/redisVectorStoreSimilaritySearch'