LangChain4J Vector Stores Configuration
Configure vector stores for Retrieval-Augmented Generation applications with LangChain4J.
When to Use
To configure vector stores when:
- Building RAG applications requiring embedding storage and retrieval
- Implementing semantic search in Java applications
- Integrating LLMs with vector databases for context-aware responses
- Configuring multi-modal embedding storage for text, images, or other data
- Setting up hybrid search combining vector similarity and full-text search
- Migrating between different vector store providers
- Optimizing vector database performance for production workloads
- Building AI-powered applications with memory and persistence
- Implementing document chunking and embedding pipelines
- Creating recommendation systems based on vector similarity
Instructions
Set Up Basic Vector Store
Configure an embedding store for vector operations:
java
1@Bean
2public EmbeddingStore<TextSegment> embeddingStore() {
3 return PgVectorEmbeddingStore.builder()
4 .host("localhost")
5 .port(5432)
6 .database("vectordb")
7 .user("username")
8 .password("password")
9 .table("embeddings")
10 .dimension(1536) // OpenAI embedding dimension
11 .createTable(true)
12 .useIndex(true)
13 .build();
14}
Use different stores for different use cases:
java
1@Configuration
2public class MultiVectorStoreConfiguration {
3
4 @Bean
5 @Qualifier("documentsStore")
6 public EmbeddingStore<TextSegment> documentsEmbeddingStore() {
7 return PgVectorEmbeddingStore.builder()
8 .table("document_embeddings")
9 .dimension(1536)
10 .build();
11 }
12
13 @Bean
14 @Qualifier("chatHistoryStore")
15 public EmbeddingStore<TextSegment> chatHistoryEmbeddingStore() {
16 return MongoDbEmbeddingStore.builder()
17 .collectionName("chat_embeddings")
18 .build();
19 }
20}
Implement Document Ingestion
Use EmbeddingStoreIngestor for automated document processing:
java
1@Bean
2public EmbeddingStoreIngestor embeddingStoreIngestor(
3 EmbeddingStore<TextSegment> embeddingStore,
4 EmbeddingModel embeddingModel) {
5
6 return EmbeddingStoreIngestor.builder()
7 .documentSplitter(DocumentSplitters.recursive(
8 300, // maxSegmentSizeInTokens
9 20, // maxOverlapSizeInTokens
10 new OpenAiTokenizer(GPT_3_5_TURBO)
11 ))
12 .embeddingModel(embeddingModel)
13 .embeddingStore(embeddingStore)
14 .build();
15}
Configure metadata-based filtering capabilities:
java
1// MongoDB with metadata field mapping
2IndexMapping indexMapping = IndexMapping.builder()
3 .dimension(1536)
4 .metadataFieldNames(Set.of("category", "source", "created_date", "author"))
5 .build();
6
7// Search with metadata filters
8EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
9 .queryEmbedding(queryEmbedding)
10 .maxResults(10)
11 .filter(and(
12 metadataKey("category").isEqualTo("technical_docs"),
13 metadataKey("created_date").isGreaterThan(LocalDate.now().minusMonths(6))
14 ))
15 .build();
Implement connection pooling and monitoring:
java
1@Bean
2public EmbeddingStore<TextSegment> optimizedPgVectorStore() {
3 HikariConfig hikariConfig = new HikariConfig();
4 hikariConfig.setJdbcUrl("jdbc:postgresql://localhost:5432/vectordb");
5 hikariConfig.setUsername("username");
6 hikariConfig.setPassword("password");
7 hikariConfig.setMaximumPoolSize(20);
8 hikariConfig.setMinimumIdle(5);
9 hikariConfig.setConnectionTimeout(30000);
10
11 DataSource dataSource = new HikariDataSource(hikariConfig);
12
13 return PgVectorEmbeddingStore.builder()
14 .dataSource(dataSource)
15 .table("embeddings")
16 .dimension(1536)
17 .useIndex(true)
18 .build();
19}
Implement Health Checks
Monitor vector store connectivity:
java
1@Component
2public class VectorStoreHealthIndicator implements HealthIndicator {
3
4 private final EmbeddingStore<TextSegment> embeddingStore;
5
6 @Override
7 public Health health() {
8 try {
9 embeddingStore.search(EmbeddingSearchRequest.builder()
10 .queryEmbedding(new Embedding(Collections.nCopies(1536, 0.0f)))
11 .maxResults(1)
12 .build());
13
14 return Health.up()
15 .withDetail("store", embeddingStore.getClass().getSimpleName())
16 .build();
17 } catch (Exception e) {
18 return Health.down()
19 .withDetail("error", e.getMessage())
20 .build();
21 }
22 }
23}
Examples
Basic RAG Application Setup
java
1@Configuration
2public class SimpleRagConfig {
3
4 @Bean
5 public EmbeddingStore<TextSegment> embeddingStore() {
6 return PgVectorEmbeddingStore.builder()
7 .host("localhost")
8 .database("rag_db")
9 .table("documents")
10 .dimension(1536)
11 .build();
12 }
13
14 @Bean
15 public ChatLanguageModel chatModel() {
16 return OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY"));
17 }
18}
Semantic Search Service
java
1@Service
2public class SemanticSearchService {
3
4 private final EmbeddingStore<TextSegment> store;
5 private final EmbeddingModel embeddingModel;
6
7 public List<String> search(String query, int maxResults) {
8 Embedding queryEmbedding = embeddingModel.embed(query).content();
9
10 EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
11 .queryEmbedding(queryEmbedding)
12 .maxResults(maxResults)
13 .minScore(0.75)
14 .build();
15
16 return store.search(request).matches().stream()
17 .map(match -> match.embedded().text())
18 .toList();
19 }
20}
Production Setup with Monitoring
java
1@Configuration
2public class ProductionVectorStoreConfig {
3
4 @Bean
5 public EmbeddingStore<TextSegment> vectorStore(
6 @Value("${vector.store.host}") String host,
7 MeterRegistry meterRegistry) {
8
9 EmbeddingStore<TextSegment> store = PgVectorEmbeddingStore.builder()
10 .host(host)
11 .database("production_vectors")
12 .useIndex(true)
13 .indexListSize(200)
14 .build();
15
16 return new MonitoredEmbeddingStore<>(store, meterRegistry);
17 }
18}
Best Practices
Choose the Right Vector Store
For Development:
- Use
InMemoryEmbeddingStore for local development and testing
- Fast setup, no external dependencies
- Data lost on application restart
For Production:
- PostgreSQL + pgvector: Excellent for existing PostgreSQL environments
- Pinecone: Managed service, good for rapid prototyping
- MongoDB Atlas: Good integration with existing MongoDB applications
- Milvus/Zilliz: High performance for large-scale deployments
Choose index types based on performance requirements:
java
1// For high recall requirements
2.indexType(IndexType.FLAT) // Exact search, slower but accurate
3
4// For balanced performance
5.indexType(IndexType.IVF_FLAT) // Good balance of speed and accuracy
6
7// For high-speed approximate search
8.indexType(IndexType.HNSW) // Fastest, slightly less accurate
Optimize Vector Dimensions
Match embedding dimensions to your model:
java
1// OpenAI text-embedding-3-small
2.dimension(1536)
3
4// OpenAI text-embedding-3-large
5.dimension(3072)
6
7// Sentence Transformers
8.dimension(384) // all-MiniLM-L6-v2
9.dimension(768) // all-mpnet-base-v2
Implement Batch Operations
Use batch operations for better performance:
java
1@Service
2public class BatchEmbeddingService {
3
4 private static final int BATCH_SIZE = 100;
5
6 public void addDocumentsBatch(List<Document> documents) {
7 for (List<Document> batch : Lists.partition(documents, BATCH_SIZE)) {
8 List<TextSegment> segments = batch.stream()
9 .map(doc -> TextSegment.from(doc.text(), doc.metadata()))
10 .collect(Collectors.toList());
11
12 List<Embedding> embeddings = embeddingModel.embedAll(segments)
13 .content();
14
15 embeddingStore.addAll(embeddings, segments);
16 }
17 }
18}
Secure Configuration
Protect sensitive configuration:
java
1// Use environment variables
2@Value("${vector.store.api.key:#{null}}")
3private String apiKey;
4
5// Validate configuration
6@PostConstruct
7public void validateConfiguration() {
8 if (StringUtils.isBlank(apiKey)) {
9 throw new IllegalStateException("Vector store API key must be configured");
10 }
11}
References
For comprehensive documentation and advanced configurations, see: