Common vector store functionality for Spring AI providing a portable abstraction layer for integrating vector databases with comprehensive filtering, similarity search, and observability support.
Get started with Spring AI Vector Store in minutes.
Add to your pom.xml:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-vector-store</artifactId>
<version>1.1.2</version>
</dependency>Add to your build.gradle:
implementation 'org.springframework.ai:spring-ai-vector-store:1.1.2'import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
// SimpleVectorStore is perfect for getting started
SimpleVectorStore vectorStore = SimpleVectorStore.builder(embeddingModel).build();Note: You need an EmbeddingModel instance. For getting started, use OpenAI's embedding model or a mock implementation.
import org.springframework.ai.document.Document;
import java.util.List;
import java.util.Map;
List<Document> documents = List.of(
new Document("Spring Boot makes it easy to create stand-alone applications",
Map.of("category", "framework", "year", 2024)),
new Document("Java is a popular programming language",
Map.of("category", "language", "year", 2023)),
new Document("Vector databases enable semantic search",
Map.of("category", "database", "year", 2024))
);
vectorStore.add(documents);import org.springframework.ai.vectorstore.SearchRequest;
// Simple search
List<Document> results = vectorStore.similaritySearch("What is Spring Boot?");
// Advanced search with configuration
SearchRequest request = SearchRequest.builder()
.query("What is Spring Boot?")
.topK(3)
.similarityThreshold(0.7)
.build();
List<Document> advancedResults = vectorStore.similaritySearch(request);
// Print results
advancedResults.forEach(doc -> {
System.out.println("Content: " + doc.getContent());
System.out.println("Metadata: " + doc.getMetadata());
});Create a configuration class:
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.embedding.openai.OpenAiEmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class VectorStoreConfig {
@Bean
public EmbeddingModel embeddingModel() {
// Configure your embedding model
return new OpenAiEmbeddingModel(
System.getenv("OPENAI_API_KEY"),
OpenAiEmbeddingOptions.builder()
.withModel("text-embedding-ada-002")
.build()
);
}
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
return SimpleVectorStore.builder(embeddingModel).build();
}
}Add to application.yml:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
vectorstore:
initialize-schema: trueOr application.properties:
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.vectorstore.initialize-schema=trueimport org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.stereotype.Service;
@Service
public class SearchService {
private final VectorStore vectorStore;
public SearchService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
public List<Document> search(String query) {
return vectorStore.similaritySearch(
SearchRequest.builder()
.query(query)
.topK(5)
.similarityThreshold(0.7)
.build()
);
}
public void addDocument(String content, Map<String, Object> metadata) {
Document doc = new Document(content, metadata);
vectorStore.add(List.of(doc));
}
}SimpleVectorStore supports JSON persistence:
import java.io.File;
import java.io.IOException;
// Save state
vectorStore.save(new File("vectorstore.json"));
// Load state on startup
SimpleVectorStore store = SimpleVectorStore.builder(embeddingModel).build();
try {
store.load(new File("vectorstore.json"));
System.out.println("Loaded existing vector store");
} catch (IOException e) {
System.out.println("Starting with empty vector store");
}@Configuration
public class VectorStoreConfig {
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
SimpleVectorStore store = SimpleVectorStore.builder(embeddingModel).build();
// Load existing data on startup
File storeFile = new File("vectorstore.json");
if (storeFile.exists()) {
try {
store.load(storeFile);
} catch (IOException e) {
// Handle error
}
}
return store;
}
}Add metadata filters to your searches:
// Text filter syntax
SearchRequest request = SearchRequest.builder()
.query("programming concepts")
.topK(5)
.filterExpression("year >= 2024 && category == 'framework'")
.build();
List<Document> results = vectorStore.similaritySearch(request);See: Filtering Guide for comprehensive filtering documentation.
// Documents get auto-generated IDs if not specified
Document doc = new Document("content", Map.of("key", "value"));
vectorStore.add(List.of(doc));
// ID is automatically generatedDocument doc = new Document(
"custom-id-123",
"content",
Map.of("key", "value")
);
vectorStore.add(List.of(doc));// Delete by ID
vectorStore.delete(List.of("doc-id-1", "doc-id-2"));
// Delete by filter (if supported)
vectorStore.delete("year < 2020");To update a document, delete the old one and add the new version:
// Delete old version
vectorStore.delete(List.of("doc-id"));
// Add updated version
Document updated = new Document("doc-id", "new content", newMetadata);
vectorStore.add(List.of(updated));import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@Test
void testVectorStoreSearch() {
// Use SimpleVectorStore for tests
VectorStore testStore = SimpleVectorStore.builder(mockEmbeddingModel).build();
testStore.add(List.of(
new Document("Spring Boot guide", Map.of("type", "tutorial")),
new Document("Java basics", Map.of("type", "reference"))
));
SearchRequest request = SearchRequest.builder()
.query("Spring framework")
.topK(1)
.build();
List<Document> results = testStore.similaritySearch(request);
assertThat(results).hasSize(1);
assertThat(results.get(0).getContent()).contains("Spring Boot");
}Solution: Documents with existing embeddings skip re-computation:
float[] precomputedEmbedding = embeddingModel.embed("text").getOutput();
Document doc = new Document("text", metadata);
doc.setEmbedding(precomputedEmbedding);
vectorStore.add(List.of(doc)); // No re-embeddingSolutions:
// Try with lower threshold
SearchRequest relaxed = SearchRequest.builder()
.query("query")
.similarityThreshold(0.5) // Lower threshold
.topK(10) // More results
.build();Solution: SimpleVectorStore is for small datasets. Use a production vector store:
// For production with large datasets
VectorStore prodStore = PineconeVectorStore.builder(embeddingModel)
.apiKey(apiKey)
.environment("us-west1-gcp")
.build();Here's a complete working example:
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.embedding.openai.OpenAiEmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.document.Document;
import java.util.List;
import java.util.Map;
public class VectorStoreExample {
public static void main(String[] args) {
// 1. Create embedding model
EmbeddingModel embeddingModel = new OpenAiEmbeddingModel(
System.getenv("OPENAI_API_KEY")
);
// 2. Create vector store
SimpleVectorStore vectorStore = SimpleVectorStore.builder(embeddingModel).build();
// 3. Add documents
List<Document> documents = List.of(
new Document("Spring Boot tutorial", Map.of("category", "framework")),
new Document("Java programming guide", Map.of("category", "language")),
new Document("Vector databases overview", Map.of("category", "database"))
);
vectorStore.add(documents);
// 4. Search
SearchRequest request = SearchRequest.builder()
.query("What is Spring Boot?")
.topK(2)
.similarityThreshold(0.7)
.filterExpression("category == 'framework'")
.build();
List<Document> results = vectorStore.similaritySearch(request);
// 5. Display results
results.forEach(doc -> {
System.out.println("Content: " + doc.getContent());
System.out.println("Metadata: " + doc.getMetadata());
System.out.println("---");
});
// 6. Save state
try {
vectorStore.save(new java.io.File("vectorstore.json"));
System.out.println("Vector store saved");
} catch (Exception e) {
e.printStackTrace();
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-ai--spring-ai-vector-store