tessl install github:giuseppe-trisciuoglio/developer-kit --skill langchain4j-vector-stores-configurationgithub.com/giuseppe-trisciuoglio/developer-kit
Configure LangChain4J vector stores for RAG applications. Use when building semantic search, integrating vector databases (PostgreSQL/pgvector, Pinecone, MongoDB, Milvus, Neo4j), implementing embedding storage/retrieval, setting up hybrid search, or optimizing vector database performance for production AI applications.
Review Score
84%
Validation Score
11/16
Implementation Score
73%
Activation Score
100%
Configure vector stores for Retrieval-Augmented Generation applications with LangChain4J.
To configure vector stores when:
Configure an embedding store for vector operations:
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return PgVectorEmbeddingStore.builder()
.host("localhost")
.port(5432)
.database("vectordb")
.user("username")
.password("password")
.table("embeddings")
.dimension(1536) // OpenAI embedding dimension
.createTable(true)
.useIndex(true)
.build();
}Use different stores for different use cases:
@Configuration
public class MultiVectorStoreConfiguration {
@Bean
@Qualifier("documentsStore")
public EmbeddingStore<TextSegment> documentsEmbeddingStore() {
return PgVectorEmbeddingStore.builder()
.table("document_embeddings")
.dimension(1536)
.build();
}
@Bean
@Qualifier("chatHistoryStore")
public EmbeddingStore<TextSegment> chatHistoryEmbeddingStore() {
return MongoDbEmbeddingStore.builder()
.collectionName("chat_embeddings")
.build();
}
}Use EmbeddingStoreIngestor for automated document processing:
@Bean
public EmbeddingStoreIngestor embeddingStoreIngestor(
EmbeddingStore<TextSegment> embeddingStore,
EmbeddingModel embeddingModel) {
return EmbeddingStoreIngestor.builder()
.documentSplitter(DocumentSplitters.recursive(
300, // maxSegmentSizeInTokens
20, // maxOverlapSizeInTokens
new OpenAiTokenizer(GPT_3_5_TURBO)
))
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.build();
}Configure metadata-based filtering capabilities:
// MongoDB with metadata field mapping
IndexMapping indexMapping = IndexMapping.builder()
.dimension(1536)
.metadataFieldNames(Set.of("category", "source", "created_date", "author"))
.build();
// Search with metadata filters
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(10)
.filter(and(
metadataKey("category").isEqualTo("technical_docs"),
metadataKey("created_date").isGreaterThan(LocalDate.now().minusMonths(6))
))
.build();Implement connection pooling and monitoring:
@Bean
public EmbeddingStore<TextSegment> optimizedPgVectorStore() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl("jdbc:postgresql://localhost:5432/vectordb");
hikariConfig.setUsername("username");
hikariConfig.setPassword("password");
hikariConfig.setMaximumPoolSize(20);
hikariConfig.setMinimumIdle(5);
hikariConfig.setConnectionTimeout(30000);
DataSource dataSource = new HikariDataSource(hikariConfig);
return PgVectorEmbeddingStore.builder()
.dataSource(dataSource)
.table("embeddings")
.dimension(1536)
.useIndex(true)
.build();
}Monitor vector store connectivity:
@Component
public class VectorStoreHealthIndicator implements HealthIndicator {
private final EmbeddingStore<TextSegment> embeddingStore;
@Override
public Health health() {
try {
embeddingStore.search(EmbeddingSearchRequest.builder()
.queryEmbedding(new Embedding(Collections.nCopies(1536, 0.0f)))
.maxResults(1)
.build());
return Health.up()
.withDetail("store", embeddingStore.getClass().getSimpleName())
.build();
} catch (Exception e) {
return Health.down()
.withDetail("error", e.getMessage())
.build();
}
}
}@Configuration
public class SimpleRagConfig {
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return PgVectorEmbeddingStore.builder()
.host("localhost")
.database("rag_db")
.table("documents")
.dimension(1536)
.build();
}
@Bean
public ChatLanguageModel chatModel() {
return OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY"));
}
}@Service
public class SemanticSearchService {
private final EmbeddingStore<TextSegment> store;
private final EmbeddingModel embeddingModel;
public List<String> search(String query, int maxResults) {
Embedding queryEmbedding = embeddingModel.embed(query).content();
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(maxResults)
.minScore(0.75)
.build();
return store.search(request).matches().stream()
.map(match -> match.embedded().text())
.toList();
}
}@Configuration
public class ProductionVectorStoreConfig {
@Bean
public EmbeddingStore<TextSegment> vectorStore(
@Value("${vector.store.host}") String host,
MeterRegistry meterRegistry) {
EmbeddingStore<TextSegment> store = PgVectorEmbeddingStore.builder()
.host(host)
.database("production_vectors")
.useIndex(true)
.indexListSize(200)
.build();
return new MonitoredEmbeddingStore<>(store, meterRegistry);
}
}For Development:
InMemoryEmbeddingStore for local development and testingFor Production:
Choose index types based on performance requirements:
// For high recall requirements
.indexType(IndexType.FLAT) // Exact search, slower but accurate
// For balanced performance
.indexType(IndexType.IVF_FLAT) // Good balance of speed and accuracy
// For high-speed approximate search
.indexType(IndexType.HNSW) // Fastest, slightly less accurateMatch embedding dimensions to your model:
// OpenAI text-embedding-3-small
.dimension(1536)
// OpenAI text-embedding-3-large
.dimension(3072)
// Sentence Transformers
.dimension(384) // all-MiniLM-L6-v2
.dimension(768) // all-mpnet-base-v2Use batch operations for better performance:
@Service
public class BatchEmbeddingService {
private static final int BATCH_SIZE = 100;
public void addDocumentsBatch(List<Document> documents) {
for (List<Document> batch : Lists.partition(documents, BATCH_SIZE)) {
List<TextSegment> segments = batch.stream()
.map(doc -> TextSegment.from(doc.text(), doc.metadata()))
.collect(Collectors.toList());
List<Embedding> embeddings = embeddingModel.embedAll(segments)
.content();
embeddingStore.addAll(embeddings, segments);
}
}
}Protect sensitive configuration:
// Use environment variables
@Value("${vector.store.api.key:#{null}}")
private String apiKey;
// Validate configuration
@PostConstruct
public void validateConfiguration() {
if (StringUtils.isBlank(apiKey)) {
throw new IllegalStateException("Vector store API key must be configured");
}
}For comprehensive documentation and advanced configurations, see: