资讯动态

在 LangChain4j 中使用 Qdrant 作为向量存储:从依赖接入、构建配置到元数据过滤实战

发布时间:2026/9/15 11:02:45 来源:尧图企业网站定制
在 LangChain4j 中使用 Qdrant 作为向量存储从依赖接入、构建配置到元数据过滤实战【免费下载链接】langchain4jLangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM providers and vector stores, and makes implementing tool calling (including MCP support), agents and RAG easy. It integrates seamlessly with enterprise Java frameworks like Quarkus and Spring Boot.项目地址: https://gitcode.com/GitHub_Trending/la/langchain4jQdrant 是一个开源的向量数据库与相似性搜索引擎LangChain4j 通过langchain4j-qdrant模块将其封装为标准EmbeddingStore实现用于持久化 embedding 向量并执行相似性检索。本文以仓库中的 qdrant.md 文档为主线结合 QdrantEmbeddingStore.java 源码完整讲解依赖接入、Builder 配置参数、增删查操作、元数据过滤机制与底层实现原理读完即可在 RAG 与语义检索场景中直接落地使用。Maven 依赖在项目中引入langchain4j-qdrant模块dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-qdrant/artifactId version1.20.0-beta30/version /dependency从模块的 pom.xml 可以看到该模块的依赖关系核心依赖langchain4j-core提供EmbeddingStore、Embedding、TextSegment、Metadata等基础模型官方 Java 客户端io.qdrant:client:1.17.0通过 gRPC 与 Qdrant 服务端通信io.grpc:grpc-protobuf:1.77.0用于 Qdrant gRPC 接口的 Protobuf 消息定义测试依赖使用 Testcontainers 的qdrant容器与langchain4j-embeddings-all-minilm-l6-v2-q量化 embedding 模型详见后文测试章节。需要注意该模块的 parent 版本为1.21.0-beta31-SNAPSHOT发布版本号以 Maven Central 实际发布的坐标为准引用时请替换为当前最新稳定版本。核心 API该集成暴露的 API 只有一个核心类QdrantEmbeddingStore— 位于包dev.langchain4j.store.embedding.qdrant实现EmbeddingStoreTextSegment接口将 Qdrant 中的一个集合collection作为一个 embedding 存储并在存储TextSegment时同步持久化其Metadata。构建 QdrantEmbeddingStore两种方式与全部配置项方式一通过 Builder 自动创建 QdrantClient最常用的方式是使用QdrantEmbeddingStore.builder()由模块内部根据主机、端口等信息创建 gRPC 客户端。Builder 的全部配置项如下来源于 QdrantEmbeddingStore.javaBuilder 方法类型默认值必填说明collectionName(String)String无必填Qdrant 集合名称构建时若为空会抛出NullPointerExceptionhost(String)Stringlocalhost否Qdrant 实例的主机地址port(int)int6334否Qdrant 的gRPC 端口注意不是 HTTP 端口 6333useTls(boolean)booleanfalse否是否启用 TLS/HTTPS 加密连接payloadTextKey(String)Stringtext_segment否文本片段在 Qdrant payload 中的字段名apiKey(String)Stringnull否Qdrant API Key用于身份认证client(QdrantClient)QdrantClientnull否直接传入自定义的QdrantClient实例最小可用示例QdrantEmbeddingStore store QdrantEmbeddingStore.builder() .collectionName(my_collection) // 必填 .build(); // host 默认 localhostport 默认 6334连接远程或云托管实例并启用认证与 TLSQdrantEmbeddingStore store QdrantEmbeddingStore.builder() .host(qdrant.example.com) .port(6334) .useTls(true) .apiKey(your-api-key) .collectionName(my_collection) .payloadTextKey(text_segment) .build();从源码可以看出构造时会通过QdrantGrpcClient.newBuilder(host, port, useTls)创建 gRPC 客户端当apiKey非空时会调用grpcClientBuilder.withApiKey(apiKey)附加认证信息见 QdrantEmbeddingStore.java。方式二传入已有的 QdrantClient当需要复用连接、自定义 gRPC 配置或管理客户端生命周期时可先自行构建QdrantClient再传入QdrantClient client new QdrantClient( QdrantGrpcClient.newBuilder(localhost, 6334, false).build()); QdrantEmbeddingStore store QdrantEmbeddingStore.builder() .client(client) // 使用已有的 QdrantClient .collectionName(my_collection) .build();Builder.build()内部会判断若client非空则使用传入的客户端否则回退到 host/port/TLS/apiKey 方式新建客户端见 QdrantEmbeddingStore.java。常用操作写入、搜索与删除QdrantEmbeddingStore实现了EmbeddingStoreTextSegment的全部标准操作可直接与 LangChain4j 的EmbeddingModel如各类 embedding 模型配合使用。写入 embedding// 添加单个 embedding仅向量 String id store.add(embedding); // 添加 embedding 文本片段文本与其 Metadata 一并写入 payload String id store.add(embedding, textSegment); // 批量添加可同时指定 id、embedding、textSegment 三个列表 ListString ids store.addAll(ids, embeddings, textSegments);源码中addAll的写入逻辑见 QdrantEmbeddingStore.java值得关注先通过ensureConsistentSizes校验三个列表长度一致空 embedding 列表直接返回每个条目构建一个PointStruct向量通过vectors(embedding.vector())写入若提供TextSegment其Metadata经ValueMapFactory.valueMap()转为 Qdrant payload同时把文本内容放入payloadTextKey指定的字段最后调用client.upsertAsync(collectionName, points).get()异步批量写入并阻塞等待结果。点 ID 的两种形式写入时若未指定 ID 会生成随机 UUID指定 ID 时toPointId会先尝试按无符号长整型Long.parseUnsignedLong解析失败则按 UUID 解析见 QdrantEmbeddingStore.java。因此同时支持整数 ID 与 UUID 两种点 ID测试 QdrantEmbeddingStoreIT.java 中专门用42验证了整数 ID 的写入与检索。相似性搜索EmbeddingSearchResultTextSegment result store.search( EmbeddingSearchRequest.builder() .queryEmbedding(queryEmbedding) .maxResults(5) .minScore(0.7) .build()); for (EmbeddingMatchTextSegment match : result.matches()) { String id match.embeddingId(); double score match.score(); TextSegment segment match.embedded(); String text segment.text(); Metadata metadata segment.metadata(); }搜索实现见 QdrantEmbeddingStore.java的关键流程构造QueryPoints使用QueryFactory.nearest(...)执行最近邻查询开启返回向量与 payloadlimit取request.maxResults()若请求携带过滤条件则通过QdrantFilterConverter.convertExpression转为 Qdrant 的Filter附加到查询上对返回的每个ScoredPoint从 payload 中还原TextSegment与Metadata并基于余弦相似度重新计算相关度分数RelevanceScore.fromCosineSimilarity(CosineSimilarity.between(embedding, referenceEmbedding))过滤掉低于minScore的结果按分数降序返回。也就是说最终返回给调用方的score是 LangChain4j 统一的相关度分数由余弦相似度换算而非 Qdrant 原始的距离值这保证了跨向量库 API 的一致性。删除操作// 按 ID 删除 store.remove(id); // 按多个 ID 批量删除 store.removeAll(ids); // 按过滤条件删除元数据过滤见下一节 store.removeAll(filter); // 清空整个集合 store.removeAll(); // 等价于 store.clearStore()其中clearStore()使用空Filter选中全部点并执行删除见 QdrantEmbeddingStore.java集成测试 QdrantEmbeddingStoreWithRemovalIT.java 专门覆盖了全部删除场景每个用例前都会清空并断言存储为空。释放资源使用完毕后调用store.close()关闭底层 gRPC 客户端对应源码中的client.close()。元数据过滤Filter 与 Qdrant 条件的映射LangChain4j 的通用Filter表达式由 QdrantFilterConverter.java 转换为 Qdrant 原生条件。该转换器支持以下过滤器类型逻辑组合And→ Qdrantmust子句Or→ Qdrantshould子句Not→ Qdrantmust_not子句比较条件映射到 Qdrant ConditionLangChain4j 过滤器支持的比较值类型Qdrant 底层实现ContainsStringStringmatchText全文匹配IsEqualToString / UUID / Boolean / Integer / Long / Float / Double字符串与布尔用match/matchKeyword整数用match(key, long)浮点用range且gte lte value因 Qdrant Match 协议无浮点字段IsNotEqualTo同上对上述条件取must_notIsGreaterThan/IsGreaterThanOrEqualTo/IsLessThan/IsLessThanOrEqualToNumberRange的gt/gte/lt/lteIsInString / UUID / Integer / LongmatchKeywords或matchValuesIsNotInString / UUID / Integer / LongmatchExceptKeywords或matchExceptValues使用示例import static dev.langchain4j.store.embedding.filter.Filter.and; import static dev.langchain4j.store.embedding.filter.Filter.eq; Filter filter and( eq(category, java), eq(year, 2024) ); EmbeddingSearchRequest request EmbeddingSearchRequest.builder() .queryEmbedding(queryEmbedding) .filter(filter) .maxResults(5) .build(); EmbeddingSearchResultTextSegment result store.search(request);注意事项源码注释与测试均明确体现见 QdrantEmbeddingStoreIT.javaIsEqualTo/IsNotEqualTo/IsIn/IsNotIn不支持浮点值只支持字符串与整数大小比较条件只接受数值对IsNotIn而言如果元数据中不存在该 key则该条不会命中未识别的过滤器类型会抛出UnsupportedOperationException不支持的比较值类型会抛出IllegalArgumentException或RuntimeException。底层实现元数据 payload 的序列化与反序列化Qdrant 以 JSON 形式在 payload 中保存附加数据模块通过两个工具类完成与 LangChain4jMetadata的双向转换ValueMapFactory.java写入方向。把Metadata.toMap()的 Java 对象转为 Qdrant 的JsonWithInt.Value支持String、Integer、Long、Double、Float、Boolean、UUID转为字符串、null、数组与嵌套 Map。注意Float在写入时经ValueFactory.value(Float)提升为 double 存储这也是过滤器对浮点相等比较用range并统一按doubleValue()换算的原因见 QdrantFilterConverter.java。不支持的 Java 类型会抛出IllegalArgumentException。ObjectFactory.java读取方向。把 Qdrant payload 的Value还原为 Java 对象支持整数、字符串、double、布尔、列表、嵌套结构与 null。读取时toEmbeddingMatch会把payloadTextKey字段单独取出作为TextSegment的文本其余字段全部还原为Metadata见 QdrantEmbeddingStore.java。因此写入时放入 Metadata 的任意字段检索时都会原样返回便于下游 RAG 组装引用信息。测试与验证Testcontainers 驱动的集成测试模块内置了完整的测试套件可作为自行搭建开发环境的参考QdrantEmbeddingStoreIT.java基于org.testcontainers.qdrant.QdrantContainer拉起qdrant/qdrant:latest容器使用AllMiniLmL6V2QuantizedEmbeddingModel生成 embedding覆盖增删查与全部元数据过滤场景QdrantEmbeddingStoreWithRemovalIT.java专门验证各删除路径QdrantEmbeddingStoreContractTest.java实现EmbeddingStoreAddAllContract与EmbeddingStoreRemoveAllContract用 Mockito 验证addAll、removeAll的契约行为QdrantFilterConverterTest.java纯单元测试验证过滤器到 Qdrant 条件的转换。测试中还揭示了集合创建的关键前提必须先创建 Qdrant 集合且向量维度要与 embedding 模型维度一致距离度量使用Distance.Cosine见 QdrantEmbeddingStoreIT.java。这一点对自建集合的读者尤为重要——QdrantEmbeddingStore本身不会自动建集向量维度、度量方式建议 Cosine都需在 Qdrant 侧通过 gRPC/HTTP API 或 Dashboard 预先配置且要与所用 embedding 模型的输出维度严格对齐。使用前提与注意事项小结端口与协议模块使用 Qdrant 的 gRPC 接口默认端口为 6334非 HTTP 的 6333useTls需与 Qdrant 服务端 TLS 配置保持一致集合预创建写入前须先在 Qdrant 中创建好集合向量维度须与 embedding 模型一致度量建议使用 Cosine点 ID 兼容ID 支持无符号长整型与 UUID 两种形式二者在检索结果中会按原类型还原Metadata 类型约束payload 字段只支持基本类型、数组与嵌套 MapUUID会被存储为字符串不受支持的类型会在写入时报错过滤能力边界浮点值不支持等值与 In/NotIn 过滤IsNotIn对缺失 key 的条目不命中编写过滤条件时需留意。结合以上内容你可以在 LangChain4j 应用中把 Qdrant 作为持久化的向量存储通过 Builder 一行完成连接配置借助标准EmbeddingStoreAPI 实现写入、相似检索与元数据过滤并利用 Testcontainers 在本地快速复现测试环境。【免费下载链接】langchain4jLangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM providers and vector stores, and makes implementing tool calling (including MCP support), agents and RAG easy. It integrates seamlessly with enterprise Java frameworks like Quarkus and Spring Boot.项目地址: https://gitcode.com/GitHub_Trending/la/langchain4j创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价