qdrant

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Qdrant 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和机器学习应用的向量数据库集成
  • 带过滤查询的高性能相似性搜索
  • 上下文感知应用的嵌入存储与检索

Instructions

操作步骤

Follow these steps to integrate Qdrant with your Java application:
按照以下步骤将Qdrant集成到你的Java应用中:

1. Deploy Qdrant Instance

1. 部署Qdrant实例

Start Qdrant using Docker for local development:
bash
docker run -p 6333:6333 -p 6334:6334 \
    -v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
    qdrant/qdrant
使用Docker启动Qdrant用于本地开发:
bash
docker run -p 6333:6333 -p 6334:6334 \
    -v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
    qdrant/qdrant

2. Add Dependencies

2. 添加依赖

Include Qdrant client dependencies in your build configuration:
xml
<dependency>
    <groupId>io.qdrant</groupId>
    <artifactId>client</artifactId>
    <version>1.15.0</version>
</dependency>
在构建配置中引入Qdrant客户端依赖:
xml
<dependency>
    <groupId>io.qdrant</groupId>
    <artifactId>client</artifactId>
    <version>1.15.0</version>
</dependency>

3. Initialize Qdrant Client

3. 初始化Qdrant客户端

Create and configure the Qdrant client:
java
QdrantClient client = new QdrantClient(
    QdrantGrpcClient.newBuilder("localhost").build()
);
创建并配置Qdrant客户端:
java
QdrantClient client = new QdrantClient(
    QdrantGrpcClient.newBuilder("localhost").build()
);

4. Create Collection

4. 创建集合

Set up a vector collection with appropriate dimensions:
java
client.createCollectionAsync("search-collection",
    VectorParams.newBuilder()
        .setDistance(Distance.Cosine)
        .setSize(384)
        .build()
).get();
设置具有合适维度的向量集合:
java
client.createCollectionAsync("search-collection",
    VectorParams.newBuilder()
        .setDistance(Distance.Cosine)
        .setSize(384)
        .build()
).get();

5. Perform Vector Operations

5. 执行向量操作

Upsert and search vectors:
java
// Upsert vectors
List<PointStruct> points = List.of(
    PointStruct.newBuilder()
        .setId(id(1))
        .setVectors(vectors(0.05f, 0.61f, 0.76f, 0.74f))
        .build()
);
client.upsertAsync("search-collection", points).get();

// Search vectors
List<ScoredPoint> results = client.queryAsync(
    QueryPoints.newBuilder()
        .setCollectionName("search-collection")
        .setLimit(5)
        .setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
        .build()
).get();
插入/更新和搜索向量:
java
// Upsert vectors
List<PointStruct> points = List.of(
    PointStruct.newBuilder()
        .setId(id(1))
        .setVectors(vectors(0.05f, 0.61f, 0.76f, 0.74f))
        .build()
);
client.upsertAsync("search-collection", points).get();

// Search vectors
List<ScoredPoint> results = client.queryAsync(
    QueryPoints.newBuilder()
        .setCollectionName("search-collection")
        .setLimit(5)
        .setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
        .build()
).get();

6. Integrate with LangChain4j

6. 与LangChain4j集成

Use LangChain4j's QdrantEmbeddingStore for RAG applications:
java
EmbeddingStore<TextSegment> embeddingStore = QdrantEmbeddingStore.builder()
    .collectionName("rag-collection")
    .host("localhost")
    .port(6334)
    .build();
使用LangChain4j的QdrantEmbeddingStore构建RAG应用:
java
EmbeddingStore<TextSegment> embeddingStore = QdrantEmbeddingStore.builder()
    .collectionName("rag-collection")
    .host("localhost")
    .port(6334)
    .build();

Getting Started: Qdrant Setup

快速开始:Qdrant设置

To begin integration, first deploy a Qdrant instance.
开始集成前,请先部署Qdrant实例。

Local Development with Docker

基于Docker的本地开发

bash
undefined
bash
undefined

Pull 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

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

通过以下方式访问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 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);
        }
    }
}

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
// 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);
    }
}

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
// 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();
    }
}

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
// 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();
}

References

参考资料

For comprehensive technical details and advanced patterns, see:
如需完整技术细节和高级模式,请查看:

Constraints and Warnings

约束与警告

  • Vector dimensions must match the embedding model; mismatched dimensions will cause errors.
  • Large vector collections require proper indexing configuration for acceptable search performance.
  • Cosine distance is recommended for normalized embeddings; Euclidean for non-normalized.
  • Qdrant gRPC API (port 6334) should be used for production; REST API (port 6333) for debugging.
  • Implement proper connection pooling to avoid connection exhaustion under load.
  • Batch upsert operations are more efficient than individual point insertions.
  • Be aware of payload size limits when storing metadata with vectors.
  • Collection recreation deletes all data; implement backup strategies for production.
  • Filtering on large datasets without proper indexing can cause performance degradation.
  • 向量维度必须与嵌入模型匹配,不匹配会导致错误。
  • 大型向量集合需要正确的索引配置才能保证可接受的搜索性能。
  • 余弦距离推荐用于归一化嵌入,欧氏距离用于非归一化嵌入。
  • 生产环境应使用Qdrant gRPC API(端口6334);REST API(端口6333)用于调试。
  • 实现适当的连接池以避免高负载下的连接耗尽。
  • 批量插入/更新操作比单个点插入更高效。
  • 存储向量元数据时注意负载大小限制。
  • 重建集合会删除所有数据,生产环境需实现备份策略。
  • 未正确索引的大型数据集上进行过滤会导致性能下降。