qdrant-vector-database-integration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseQdrant Vector Database Integration
Qdrant向量数据库集成
Overview
概述
Qdrant is an AI-native vector database for semantic search and similarity retrieval. This skill provides patterns for integrating Qdrant with Java applications, focusing on Spring Boot integration and LangChain4j framework support. Enable efficient vector search capabilities for RAG systems, recommendation engines, and semantic search applications.
Qdrant是一款面向语义搜索和相似度检索的AI原生向量数据库。本方案提供了Qdrant与Java应用的集成模式,重点关注Spring Boot集成和LangChain4j框架支持。可为RAG系统、推荐引擎和语义搜索应用提供高效的向量搜索能力。
When to Use
适用场景
Use this skill when implementing:
- Semantic search or recommendation systems in Spring Boot applications
- Retrieval-Augmented Generation (RAG) pipelines with Java and LangChain4j
- Vector database integration for AI and machine learning applications
- High-performance similarity search with filtered queries
- Embedding storage and retrieval for context-aware applications
以下场景可使用本方案:
- 在Spring Boot应用中实现语义搜索或推荐系统
- 基于Java和LangChain4j构建检索增强生成(RAG)流水线
- 为AI和机器学习应用集成向量数据库
- 带过滤查询的高性能相似度搜索
- 为上下文感知应用实现嵌入存储与检索
Getting Started: Qdrant Setup
快速开始:Qdrant部署
To begin integration, first deploy a Qdrant instance.
开始集成前,需先部署Qdrant实例。
Local Development with Docker
使用Docker进行本地开发
bash
undefinedbash
undefinedPull the latest Qdrant image
拉取最新Qdrant镜像
docker pull qdrant/qdrant
docker pull qdrant/qdrant
Run the Qdrant container
运行Qdrant容器
docker run -p 6333:6333 -p 6334:6334
-v "$(pwd)/qdrant_storage:/qdrant/storage:z"
qdrant/qdrant
-v "$(pwd)/qdrant_storage:/qdrant/storage:z"
qdrant/qdrant
Access Qdrant via:
- **REST API**: `http://localhost:6333`
- **gRPC API**: `http://localhost:6334` (used by Java client)docker run -p 6333:6333 -p 6334:6334
-v "$(pwd)/qdrant_storage:/qdrant/storage:z"
qdrant/qdrant
-v "$(pwd)/qdrant_storage:/qdrant/storage:z"
qdrant/qdrant
通过以下方式访问Qdrant:
- **REST API**:`http://localhost:6333`
- **gRPC API**:`http://localhost:6334`(Java客户端使用)Core Java Client Integration
核心Java客户端集成
Add dependencies to your build configuration and initialize the client for programmatic access.
在构建配置中添加依赖并初始化客户端,以实现程序化访问。
Dependency Configuration
依赖配置
Maven:
xml
<dependency>
<groupId>io.qdrant</groupId>
<artifactId>client</artifactId>
<version>1.15.0</version>
</dependency>Gradle:
gradle
implementation 'io.qdrant:client:1.15.0'Maven:
xml
<dependency>
<groupId>io.qdrant</groupId>
<artifactId>client</artifactId>
<version>1.15.0</version>
</dependency>Gradle:
gradle
implementation 'io.qdrant:client:1.15.0'Client Initialization
客户端初始化
Create and configure the Qdrant client for application use:
java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
// Basic local connection
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost").build());
// Secure connection with API key
QdrantClient secureClient = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost", 6334, false)
.withApiKey("YOUR_API_KEY")
.build());
// Managed connection with TLS
QdrantClient tlsClient = new QdrantClient(
QdrantGrpcClient.newBuilder(channel)
.withApiKey("YOUR_API_KEY")
.build());创建并配置Qdrant客户端供应用使用:
java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
// 基础本地连接
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost").build());
// 带API密钥的安全连接
QdrantClient secureClient = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost", 6334, false)
.withApiKey("YOUR_API_KEY")
.build());
// 带TLS的托管连接
QdrantClient tlsClient = new QdrantClient(
QdrantGrpcClient.newBuilder(channel)
.withApiKey("YOUR_API_KEY")
.build());Collection Management
集合管理
Create and configure vector collections with appropriate distance metrics and dimensions.
创建并配置带有合适距离度量和维度的向量集合。
Create Collections
创建集合
java
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import java.util.concurrent.ExecutionException;
// Create a collection with cosine distance
client.createCollectionAsync("search-collection",
VectorParams.newBuilder()
.setDistance(Distance.Cosine)
.setSize(384)
.build()).get();
// Create collection with configuration
client.createCollectionAsync("recommendation-engine",
VectorParams.newBuilder()
.setDistance(Distance.Euclidean)
.setSize(512)
.build()).get();java
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import java.util.concurrent.ExecutionException;
// 创建使用余弦距离的集合
client.createCollectionAsync("search-collection",
VectorParams.newBuilder()
.setDistance(Distance.Cosine)
.setSize(384)
.build()).get();
// 创建带自定义配置的集合
client.createCollectionAsync("recommendation-engine",
VectorParams.newBuilder()
.setDistance(Distance.Euclidean)
.setSize(512)
.build()).get();Vector Operations
向量操作
Perform common vector operations including upsert, search, and filtering.
执行常见的向量操作,包括插入更新、搜索和过滤。
Upsert Points
插入更新向量点
java
import io.qdrant.client.grpc.Points.PointStruct;
import java.util.List;
import java.util.Map;
import static io.qdrant.client.PointIdFactory.id;
import static io.qdrant.client.ValueFactory.value;
import static io.qdrant.client.VectorsFactory.vectors;
// Batch upsert vector points
List<PointStruct> points = List.of(
PointStruct.newBuilder()
.setId(id(1))
.setVectors(vectors(0.05f, 0.61f, 0.76f, 0.74f))
.putAllPayload(Map.of(
"title", value("Spring Boot Documentation"),
"content", value("Spring Boot framework documentation")
))
.build(),
PointStruct.newBuilder()
.setId(id(2))
.setVectors(vectors(0.19f, 0.81f, 0.75f, 0.11f))
.putAllPayload(Map.of(
"title", value("Qdrant Vector Database"),
"content", value("Vector database for AI applications")
))
.build()
);
client.upsertAsync("search-collection", points).get();java
import io.qdrant.client.grpc.Points.PointStruct;
import java.util.List;
import java.util.Map;
import static io.qdrant.client.PointIdFactory.id;
import static io.qdrant.client.ValueFactory.value;
import static io.qdrant.client.VectorsFactory.vectors;
// 批量插入更新向量点
List<PointStruct> points = List.of(
PointStruct.newBuilder()
.setId(id(1))
.setVectors(vectors(0.05f, 0.61f, 0.76f, 0.74f))
.putAllPayload(Map.of(
"title", value("Spring Boot Documentation"),
"content", value("Spring Boot framework documentation")
))
.build(),
PointStruct.newBuilder()
.setId(id(2))
.setVectors(vectors(0.19f, 0.81f, 0.75f, 0.11f))
.putAllPayload(Map.of(
"title", value("Qdrant Vector Database"),
"content", value("Vector database for AI applications")
))
.build()
);
client.upsertAsync("search-collection", points).get();Vector Search
向量搜索
java
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.ScoredPoint;
import static io.qdrant.client.QueryFactory.nearest;
import java.util.List;
// Basic similarity search
List<ScoredPoint> results = client.queryAsync(
QueryPoints.newBuilder()
.setCollectionName("search-collection")
.setLimit(5)
.setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
.build()
).get();
// Search with filters
List<ScoredPoint> filteredResults = client.searchAsync(
SearchPoints.newBuilder()
.setCollectionName("search-collection")
.addAllVector(List.of(0.6235f, 0.123f, 0.532f, 0.123f))
.setFilter(Filter.newBuilder()
.addMust(range("rand_number",
Range.newBuilder().setGte(3).build()))
.build())
.setLimit(5)
.build()).get();java
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.ScoredPoint;
import static io.qdrant.client.QueryFactory.nearest;
import java.util.List;
// 基础相似度搜索
List<ScoredPoint> results = client.queryAsync(
QueryPoints.newBuilder()
.setCollectionName("search-collection")
.setLimit(5)
.setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
.build()
).get();
// 带过滤条件的搜索
List<ScoredPoint> filteredResults = client.searchAsync(
SearchPoints.newBuilder()
.setCollectionName("search-collection")
.addAllVector(List.of(0.6235f, 0.123f, 0.532f, 0.123f))
.setFilter(Filter.newBuilder()
.addMust(range("rand_number",
Range.newBuilder().setGte(3).build()))
.build())
.setLimit(5)
.build()).get();Spring Boot Integration
Spring Boot集成
Integrate Qdrant with Spring Boot using dependency injection and proper configuration.
使用依赖注入和适当配置将Qdrant与Spring Boot集成。
Configuration Class
配置类
java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QdrantConfig {
@Value("${qdrant.host:localhost}")
private String host;
@Value("${qdrant.port:6334}")
private int port;
@Value("${qdrant.api-key:}")
private String apiKey;
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient grpcClient = QdrantGrpcClient.newBuilder(host, port, false)
.withApiKey(apiKey)
.build();
return new QdrantClient(grpcClient);
}
}java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QdrantConfig {
@Value("${qdrant.host:localhost}")
private String host;
@Value("${qdrant.port:6334}")
private int port;
@Value("${qdrant.api-key:}")
private String apiKey;
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient grpcClient = QdrantGrpcClient.newBuilder(host, port, false)
.withApiKey(apiKey)
.build();
return new QdrantClient(grpcClient);
}
}Service Layer Implementation
服务层实现
java
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service
public class VectorSearchService {
private final QdrantClient qdrantClient;
public VectorSearchService(QdrantClient qdrantClient) {
this.qdrantClient = qdrantClient;
}
public List<ScoredPoint> search(String collectionName, List<Float> queryVector) {
try {
return qdrantClient.queryAsync(
QueryPoints.newBuilder()
.setCollectionName(collectionName)
.setLimit(5)
.setQuery(nearest(queryVector))
.build()
).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Qdrant search failed", e);
}
}
public void upsertPoints(String collectionName, List<PointStruct> points) {
try {
qdrantClient.upsertAsync(collectionName, points).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Qdrant upsert failed", e);
}
}
}java
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service
public class VectorSearchService {
private final QdrantClient qdrantClient;
public VectorSearchService(QdrantClient qdrantClient) {
this.qdrantClient = qdrantClient;
}
public List<ScoredPoint> search(String collectionName, List<Float> queryVector) {
try {
return qdrantClient.queryAsync(
QueryPoints.newBuilder()
.setCollectionName(collectionName)
.setLimit(5)
.setQuery(nearest(queryVector))
.build()
).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Qdrant搜索失败", e);
}
}
public void upsertPoints(String collectionName, List<PointStruct> points) {
try {
qdrantClient.upsertAsync(collectionName, points).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Qdrant插入更新失败", e);
}
}
}LangChain4j Integration
LangChain4j集成
Leverage LangChain4j for high-level vector store abstractions and RAG implementations.
利用LangChain4j实现高级向量存储抽象和RAG方案。
Dependency Setup
依赖配置
Maven:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
<version>1.7.0</version>
</dependency>Maven:
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
<version>1.7.0</version>
</dependency>QdrantEmbeddingStore Configuration
QdrantEmbeddingStore配置
java
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.embedding.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.qdrant.QdrantEmbeddingStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Langchain4jConfig {
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return QdrantEmbeddingStore.builder()
.collectionName("rag-collection")
.host("localhost")
.port(6334)
.apiKey("YOUR_API_KEY")
.build();
}
@Bean
public EmbeddingModel embeddingModel() {
return new AllMiniLmL6V2EmbeddingModel();
}
@Bean
public EmbeddingStoreIngestor embeddingStoreIngestor(
EmbeddingStore<TextSegment> embeddingStore,
EmbeddingModel embeddingModel) {
return EmbeddingStoreIngestor.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.build();
}
}java
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.embedding.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.qdrant.QdrantEmbeddingStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Langchain4jConfig {
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return QdrantEmbeddingStore.builder()
.collectionName("rag-collection")
.host("localhost")
.port(6334)
.apiKey("YOUR_API_KEY")
.build();
}
@Bean
public EmbeddingModel embeddingModel() {
return new AllMiniLmL6V2EmbeddingModel();
}
@Bean
public EmbeddingStoreIngestor embeddingStoreIngestor(
EmbeddingStore<TextSegment> embeddingStore,
EmbeddingModel embeddingModel) {
return EmbeddingStoreIngestor.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.build();
}
}RAG Service Implementation
RAG服务实现
java
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RagService {
private final EmbeddingStoreIngestor ingestor;
public RagService(EmbeddingStoreIngestor ingestor) {
this.ingestor = ingestor;
}
public void ingestDocument(String text) {
TextSegment segment = TextSegment.from(text);
ingestor.ingest(segment);
}
public List<TextSegment> findRelevant(String query) {
EmbeddingStore<TextSegment> embeddingStore = ingestor.getEmbeddingStore();
return embeddingStore.findRelevant(
ingestor.getEmbeddingModel().embed(query).content(),
5,
0.7
).stream()
.map(match -> match.embedded())
.toList();
}
}java
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RagService {
private final EmbeddingStoreIngestor ingestor;
public RagService(EmbeddingStoreIngestor ingestor) {
this.ingestor = ingestor;
}
public void ingestDocument(String text) {
TextSegment segment = TextSegment.from(text);
ingestor.ingest(segment);
}
public List<TextSegment> findRelevant(String query) {
EmbeddingStore<TextSegment> embeddingStore = ingestor.getEmbeddingStore();
return embeddingStore.findRelevant(
ingestor.getEmbeddingModel().embed(query).content(),
5,
0.7
).stream()
.map(match -> match.embedded())
.toList();
}
}Examples
示例
Basic Search Implementation
基础搜索实现
java
// Create simple search endpoint
@RestController
@RequestMapping("/api/search")
public class SearchController {
private final VectorSearchService searchService;
public SearchController(VectorSearchService searchService) {
this.searchService = searchService;
}
@GetMapping
public List<ScoredPoint> search(@RequestParam String query) {
// Convert query to embedding (requires embedding model)
List<Float> queryVector = embeddingModel.embed(query).content().vectorAsList();
return searchService.search("documents", queryVector);
}
}java
// 创建简单搜索端点
@RestController
@RequestMapping("/api/search")
public class SearchController {
private final VectorSearchService searchService;
public SearchController(VectorSearchService searchService) {
this.searchService = searchService;
}
@GetMapping
public List<ScoredPoint> search(@RequestParam String query) {
// 将查询转换为嵌入向量(需嵌入模型)
List<Float> queryVector = embeddingModel.embed(query).content().vectorAsList();
return searchService.search("documents", queryVector);
}
}Best Practices
最佳实践
Vector Database Configuration
向量数据库配置
- Use appropriate distance metrics: Cosine for text, Euclidean for numerical data
- Optimize vector dimensions based on embedding model specifications
- Configure proper collection naming conventions
- Monitor performance and optimize search parameters
- 使用合适的距离度量:文本数据用余弦距离,数值数据用欧氏距离
- 根据嵌入模型规格优化向量维度
- 配置规范的集合命名规则
- 监控性能并优化搜索参数
Spring Boot Integration
Spring Boot集成
- Always use constructor injection for dependency injection
- Handle async operations with proper exception handling
- Configure connection timeouts and retry policies
- Use proper bean configuration for production environments
- 始终使用构造函数注入进行依赖注入
- 为异步操作添加适当的异常处理
- 配置连接超时和重试策略
- 为生产环境使用正确的Bean配置
Security Considerations
安全注意事项
- Never hardcode API keys in code
- Use environment variables or Spring configuration properties
- Implement proper authentication and authorization
- Use TLS for production connections
- 切勿在代码中硬编码API密钥
- 使用环境变量或Spring配置属性
- 实现适当的认证和授权机制
- 生产环境使用TLS连接
Performance Optimization
性能优化
- Batch operations for bulk upserts
- Use appropriate limits and filters
- Monitor memory usage and connection pooling
- Consider sharding for large datasets
- 批量处理批量插入更新操作
- 使用合适的限制条件和过滤规则
- 监控内存使用和连接池情况
- 针对大型数据集考虑分片
Advanced Patterns
进阶模式
Multi-tenant Vector Storage
多租户向量存储
java
// Implement collection-based multi-tenancy
public class MultiTenantVectorService {
private final QdrantClient client;
public void upsertForTenant(String tenantId, List<PointStruct> points) {
String collectionName = "tenant_" + tenantId + "_documents";
client.upsertAsync(collectionName, points).get();
}
}java
// 实现基于集合的多租户模式
public class MultiTenantVectorService {
private final QdrantClient client;
public void upsertForTenant(String tenantId, List<PointStruct> points) {
String collectionName = "tenant_" + tenantId + "_documents";
client.upsertAsync(collectionName, points).get();
}
}Hybrid Search with Filters
带过滤的混合搜索
java
// Combine vector similarity with metadata filtering
public List<ScoredPoint> hybridSearch(String collectionName, List<Float> queryVector,
String category, Date dateRange) {
Filter filter = Filter.newBuilder()
.addMust(range("created_at",
Range.newBuilder().setGte(dateRange.getTime()).build()))
.addMust(exactMatch("category", category))
.build();
return client.searchAsync(
SearchPoints.newBuilder()
.setCollectionName(collectionName)
.addAllVector(queryVector)
.setFilter(filter)
.build()
).get();
}java
// 结合向量相似度与元数据过滤
public List<ScoredPoint> hybridSearch(String collectionName, List<Float> queryVector,
String category, Date dateRange) {
Filter filter = Filter.newBuilder()
.addMust(range("created_at",
Range.newBuilder().setGte(dateRange.getTime()).build()))
.addMust(exactMatch("category", category))
.build();
return client.searchAsync(
SearchPoints.newBuilder()
.setCollectionName(collectionName)
.addAllVector(queryVector)
.setFilter(filter)
.build()
).get();
}References
参考资料
For comprehensive technical details and advanced patterns, see:
- Qdrant API Reference - Complete client API documentation
- Complete Spring Boot Examples - Full application implementations
- Official Qdrant Documentation - Core documentation
- LangChain4j Documentation - Framework-specific patterns
如需了解全面的技术细节和进阶模式,请查看:
- Qdrant API参考 - 完整的客户端API文档
- 完整Spring Boot示例 - 完整的应用实现
- Qdrant官方文档 - 核心文档
- LangChain4j文档 - 框架专属方案