首页 / 资讯中心 / 文章详情

LangChain4j 集成 Elasticsearch 实战指南:EmbeddingStore 向量存储与 ContentRetriever 检索器完整解析

LangChain4j 集成 Elasticsearch 实战指南:EmbeddingStore 向量存储与 ContentRetriever 检索器完整解析 ★ FEATURED ARTICLE
LangChain4j 集成 Elasticsearch 实战指南EmbeddingStore 向量存储与 ContentRetriever 检索器完整解析【免费下载链接】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本篇指南围绕 LangChain4j 官方仓库中的langchain4j-elasticsearch模块展开系统讲解如何将 Elasticsearch 同时用作 Embedding 向量存储ElasticsearchEmbeddingStore与 RAG 内容检索器ElasticsearchContentRetriever。读完本文你将掌握Maven 依赖引入、ElasticsearchClient 创建、构建参数全解析、四种检索配置kNN / scriptScore / 全文 / 混合的选型与底层实现原理以及如何通过自定义ElasticsearchConfiguration实现完全定制化的搜索逻辑。模块概述一个索引两种身份langchain4j-elasticsearch是 LangChain4j 与 Elasticsearch 的官方集成模块其核心定位是把 Elasticsearch 索引同时当作Embedding 存储embedding store和内容检索器content retriever使用。模块中两个核心类分别为ElasticsearchEmbeddingStore实现EmbeddingStoreTextSegment接口负责把Embedding与TextSegment写入 Elasticsearch 索引并按向量相似度检索ElasticsearchContentRetriever实现ContentRetriever接口面向 RAG 场景接收用户Query后返回相关Content列表。两个类都继承自AbstractElasticsearchEmbeddingStore从源码结构看ContentRetriever内部复用 EmbeddingStore 的索引读写与匹配映射能力只是额外封装了查询文本 → 嵌入向量 → 检索 → 包装为 Content的完整链路。它们都需要一个 Elasticsearch 官方的 Java 客户端ElasticsearchClient来连接服务器。引入依赖与版本基线在pom.xml中声明如下依赖dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-elasticsearch/artifactId version1.20.0-beta30/version /dependency需要注意两点当前仓库中langchain4j-elasticsearch的父工程版本为1.21.0-beta31-SNAPSHOT见 langchain4j-elasticsearch/pom.xml属于开发快照版本实际使用时请以 Maven Central 上已发布的正式版本号为准。该模块底层通过官方co.elastic.clients:elasticsearch-java客户端仓库当前锁定的版本为9.3.1与 Elasticsearch 服务器通信同时保留了elasticsearch-rest-client等兼容依赖源码中已标注为 deprecated后续版本将移除。因此建议服务端尽量使用 9.x 版本以保证与客户端能力对齐。第一步创建 ElasticsearchClient无论是 EmbeddingStore 还是 ContentRetriever连接服务器都依赖ElasticsearchClient。最常见的创建方式是基于主机地址与 API KeyString apiKey VnVhQ2ZHY0JDZGJrU...; ElasticsearchClient client ElasticsearchClient.of(ec - ec .host(https://localhost:9200) .apiKey(apiKey));Elasticsearch 官方 Java 客户端支持多种连接方式用户名密码、API Key、云托管连接等具体可以参考 Elasticsearch 官方的连接文档按需选择。连接方式的多样性也是该模块要求外部传入ElasticsearchClient而非自行封装连接参数的原因。ElasticsearchEmbeddingStore向量存储的构建与使用构建与默认行为创建ElasticsearchEmbeddingStore只需传入客户端ElasticsearchEmbeddingStore store ElasticsearchEmbeddingStore.builder() .client(client) .build();从 ElasticsearchEmbeddingStore.java 的 Builder 实现可以看到全部默认值以上代码等价于显式写法ElasticsearchEmbeddingStore store ElasticsearchEmbeddingStore.builder() .client(client) .configuration(ElasticsearchConfigurationKnn.builder().build()) .indexName(default) .build();Builder 提供两个核心选项选项默认值说明indexNamedefault使用的 Elasticsearch 索引名称索引不存在时会自动创建configurationElasticsearchConfigurationKnn决定检索方式的ElasticsearchConfiguration实现需要特别提醒源码中serverUrl、apiKey、userName、password、restClient、dimension等 Builder 方法均已被标记为Deprecated(forRemoval true)后续版本将彻底移除。当前推荐且唯一的接入方式是client(ElasticsearchClient)。其中dimension参数已被忽略源码中直接记录警告日志Setting the dimension is deprecated. This value is ignored.向量维度由实际写入的 Embedding 自动决定。索引无需 embedding 的纯文本文档ElasticsearchEmbeddingStore在标准add(Embedding, TextSegment)系列方法之外还支持直接索引纯文本、不计算 embeddingstore.add(Printer troubleshooting guide); // 自动生成 id store.add(my-id, Printer troubleshooting guide); // 使用自定义 id store.addAllText(List.of(First guide, Second guide)); // 批量写入从 AbstractElasticsearchEmbeddingStore.java 的源码看这三个方法内部走的是bulkIndexText构造的Document只包含text与metadata字段不携带vector字段。由于这类文档没有向量任何向量检索kNN 或 scriptScore都不会返回它们但它们依然可以被全文检索命中。因此单一索引可以同时容纳带向量的文档与纯文本文档配合ElasticsearchConfigurationFullText或ElasticsearchConfigurationHybrid就能同时以两种方式搜索同一个索引。此外ElasticsearchConfigurationScript的向量检索实现中特意加入了对vector字段的exists查询见下文实现细节确保纯文本文档在 scriptScore 检索时被排除不会产生无意义匹配。ElasticsearchContentRetrieverRAG 内容检索ContentRetriever 除了客户端外还必须提供一个EmbeddingModel用于把查询文本转成向量EmbeddingModel embeddingModel new AllMiniLmL6V2QuantizedEmbeddingModel();示例中的AllMiniLmL6V2QuantizedEmbeddingModel来自langchain4j-embeddings-all-minilm-l6-v2-q模块这也是本模块测试代码实际使用的本地量化嵌入模型见 langchain4j-elasticsearch/pom.xml 的 test 依赖。创建检索器ElasticsearchContentRetriever contentRetriever ElasticsearchContentRetriever.builder() .client(client) .embeddingModel(embeddingModel) .build();其 BuilderElasticsearchContentRetriever.java提供以下选项选项默认值说明configurationElasticsearchConfigurationKnn检索方式配置见下节四种实现indexNamedefault索引名称不存在时自动创建maxResults3最多返回的结果条数minScore0.0结果的最低相关分阈值score ≥ minScore 才返回filternull检索时应用的元数据Filter为空则不过滤上述代码等价于ElasticsearchContentRetriever contentRetriever ElasticsearchContentRetriever.builder() .client(client) .embeddingModel(embeddingModel) .configuration(ElasticsearchConfigurationKnn.builder().build()) .indexName(default) .maxResults(3) .minScore(0.0) .filter(null) .build();从retrieve(Query)方法的源码ElasticsearchContentRetriever.java可以看到检索器内部的分支逻辑若配置为ElasticsearchConfigurationFullText则直接构造FullTextSearchRequest走全文检索否则先调用embeddingModel.embed(query.text())把查询文本向量化再走向量检索若配置为 Hybrid则额外拼接文本查询执行混合检索。检索结果会被包装为携带ContentMetadata.SCORE与ContentMetadata.EMBEDDING_ID的Content供 RAG 流水线下游使用。ElasticsearchConfiguration四种检索方式与选型ElasticsearchConfiguration是一个接口ElasticsearchConfiguration.java定义了模块与 Elasticsearch 服务器的交互契约。其中vectorSearch、fullTextSearch、hybridSearch三个默认方法分别对应向量、全文、混合检索未实现的配置调用时会抛出UnsupportedOperationException。接口还预定义了字段常量VECTOR_FIELD vector与TEXT_FIELD text即索引中文档的向量字段名与文本字段名。模块内置四种实现覆盖了 RAG 场景的主要检索策略配置实现底层查询适用对象特点ElasticsearchConfigurationKnn近似 kNN 查询Store Retriever默认速度快、近似结果ElasticsearchConfigurationScriptscriptScore 查询Store Retriever精确余弦相似度、较慢ElasticsearchConfigurationFullTextmatch 全文查询仅 Retriever无需向量走 BM25ElasticsearchConfigurationHybridRRF 混合检索仅 Retriever向量 全文融合需付费 License统一的创建方式都是各自的 BuilderElasticsearchConfiguration configuration ElasticsearchConfigurationKnn.builder().build();ElasticsearchConfigurationKnn默认的近似向量检索kNN 配置使用 Elasticsearch 的近似最近邻ANN查询是ElasticsearchEmbeddingStore与ElasticsearchContentRetriever的默认配置。适合数据量大、对速度敏感、能接受近似精度的场景。Builder 提供两个选项numCandidates检索时每个分片考虑的候选邻居数量默认null即使用 Elasticsearch 服务端默认值。从 ElasticsearchConfigurationKnn.java 的注释可以看到该值不能超过 10,000增大num_candidates通常能提升最终结果的准确性但会牺牲检索性能includeVectorResponse是否在响应中携带向量字段默认false。注意针对 Elasticsearch 9.2 服务端从 Elasticsearch 服务器 9.2 版本起向量字段默认从响应中排除。如果确实需要在响应中拿到向量不推荐会显著增大响应体积请在 Builder 中显式开启ElasticsearchConfigurationKnn configuration ElasticsearchConfigurationKnn.builder() .includeVectorResponse(true) .build();同时注意反向兼容问题在 AbstractElasticsearchEmbeddingStore.java 中若服务端版本早于 9.2 而你又设置了includeVectorResponse请求会抛出自带Unknown key for a VALUE_BOOLEAN in [exclude_vectors]错误的异常模块会记录警告提示移除该属性。从 ElasticsearchConfigurationKnn.java 的vectorSearch实现可以看到完整请求组装逻辑构造KnnQuery时指定fieldVECTOR_FIELD、查询向量为embeddingSearchRequest.queryEmbedding().vectorAsList()若embeddingSearchRequest.filter()非空则通过ElasticsearchMetadataFilterMapper.map转换为 ES 查询条件最后以.size(maxResults)与.minScore(minScore)下发检索。ElasticsearchConfigurationScript精确的余弦相似度检索scriptScore 配置使用 Elasticsearch 的 scriptScore 查询做向量相似度检索采用余弦相似度。与 kNN 的近似结果不同它是逐文档精确打分的暴力实现源码注释中明确描述为 exact brute force implementation, slower, 100% accurate适合数据量不大但对精度要求高的场景。Store 与 Retriever 均可用。ElasticsearchConfiguration configuration ElasticsearchConfigurationScript.builder().build();Builder 同样提供includeVectorResponse选项默认false9.2 服务端下如需返回向量可显式开启用法与 kNN 配置相同。其核心实现ElasticsearchConfigurationScript.java有两点值得关注打分脚本为(cosineSimilarity(params.query_vector, vector) 1.0) / 2把原始余弦相似度值域 -11归一化映射到 01minScore阈值即作用于归一化后的分数查询条件中强制叠加了对vector字段的exists查询——即使没有显式 filter纯文本文档也会被排除在打分之外避免无向量文档被错误匹配。ElasticsearchConfigurationFullText纯文本全文检索全文配置基于 Elasticsearch 的match查询对TEXT_FIELD字段只能用于ElasticsearchContentRetriever。它的价值在于无需嵌入模型即可在同一索引上检索那些没有向量的纯文本文档实现带向量文档按语义检索、纯文本文档按关键词检索的混合索引用法。ElasticsearchConfiguration configuration ElasticsearchConfigurationFullText.builder().build();从 ElasticsearchConfigurationFullText.java 的实现可见接收FullTextSearchRequest的新版方法会把request.filter()通过 bool 查询的filter子句与 match 查询叠加并应用size(maxResults)与minScore(minScore)。一个重要的分数差异全文检索的分数是BM25 分数未经归一化可能大于 1而向量检索的分数通常归一化在 01 之间。因此当你在 FullText 与向量检索之间切换时minScore的取值需要重新校准不能直接套用。ElasticsearchConfigurationHybrid向量 全文的混合检索混合配置使用 Elasticsearch 的 RRFReciprocal Rank Fusion倒数排名融合机制将 kNN 向量检索与全文检索两条结果线融合后统一排序仅适用于ElasticsearchContentRetriever且需要 Elasticsearch 企业版 License 或试用授权。ElasticsearchConfiguration configuration ElasticsearchConfigurationHybrid.builder().build();Builder 提供numCandidates与includeVectorResponse两个选项含义与 kNN 配置一致。在 ElasticsearchConfigurationHybrid.java 的实现中knn与k两个必填参数的计算逻辑是若显式指定了numCandidates则k min(numCandidates, maxResults)否则两者都取maxResults模拟 Elasticsearch 对 KnnQuery 的默认推算方式。全文侧使用TEXT_FIELD的 match 查询两侧共用同一个元数据 filter最终通过retriever.rrf(...)融合两条检索线。自定义配置实现 ElasticsearchConfiguration 接口当内置配置无法满足需求时可以直接实现ElasticsearchConfiguration接口自由定制三种检索的实现public class MyElasticsearchConfiguration implements ElasticsearchConfiguration { Override SearchResponseDocument vectorSearch( ElasticsearchClient client, String indexName, EmbeddingSearchRequest embeddingSearchRequest) { // 自定义向量检索实现 } Override SearchResponseDocument fullTextSearch( ElasticsearchClient client, String indexName, FullTextSearchRequest request) { // 自定义全文检索实现 } Override SearchResponseDocument hybridSearch( ElasticsearchClient client, String indexName, EmbeddingSearchRequest embeddingSearchRequest, String textQuery) { // 自定义混合检索实现 } }只需实现与自身场景相关的方法即可无需全部覆盖vectorSearch向量相似度检索Store 与 Retriever 都会用到fullTextSearch(..., FullTextSearchRequest)全文检索仅 Retriever 使用hybridSearch混合检索仅 Retriever 使用。仓库测试目录中就提供了一个完整的自定义实现范例ElasticsearchConfigurationCustom.java 及其集成测试 ElasticsearchConfigurationCustomIT.java可以作为自定义配置的参考模板。关于FullTextSearchRequest有一个必须注意的契约该请求对象FullTextSearchRequest.java携带了textQuery必填、maxResults默认 3、minScore默认 0.0以及filter。自定义实现有责任自行应用maxResults、minScore与filter否则可能返回不满足过滤条件的文档。关于弃用的旧版全文方法接口中还保留着一个已标记Deprecated(forRemoval true)的旧版方法fullTextSearch(ElasticsearchClient, String, String textQuery)。仅实现旧方法的配置仍然可以工作但此时检索器的maxResults、minScore与filter会被忽略且模块会记录警告日志见 ElasticsearchConfiguration.java 的默认回退逻辑。请优先实现接收FullTextSearchRequest的新版方法。元数据过滤与数据删除模块完整支持元数据存储与过滤TextSegment的Metadata会随文档一起写入索引检索时EmbeddingSearchRequest或FullTextSearchRequest携带的Filter会经ElasticsearchMetadataFilterMapper转换为 Elasticsearch 查询条件kNN 的filter子句、scriptScore 的 bool 过滤、FullText 的 bool 过滤、Hybrid 双侧过滤均已覆盖。删除操作同样完整AbstractElasticsearchEmbeddingStore.javaremoveAll(CollectionString ids)按文档 id 批量删除removeAll(Filter filter)按元数据过滤条件删除底层走deleteByQueryremoveAll()直接删除整个索引而非逐条删除文档这是 Elasticsearch 实现刻意采用的策略删除前请确认索引可重建。测试与验证方式仓库为整个模块提供了完整的集成测试套件位于 langchain4j-elasticsearch/src/test覆盖了 kNN / Script / FullText / Hybrid 四种配置、maxResults与minScore边界、索引删除等场景。测试可通过三种方式运行见 langchain4j-elasticsearch/pom.xml 中的说明# 方式一Elasticsearch Cloud mvn verify -DELASTICSEARCH_CLOUD_URLhttps://URL.elastic-cloud.com -DELASTICSEARCH_CLOUD_API_KEYTHE_KEY # 方式二本地已运行的 Elasticsearch mvn verify -DELASTICSEARCH_LOCAL_URLhttps://localhost:9200 -DELASTICSEARCH_LOCAL_PASSWORDchangeme # 方式三Testcontainers 自动启动容器 mvn verify其中方式三无需任何外部服务Testcontainers 会自动拉起 Elasticsearch 容器相关依赖已在 pom 中声明是最便捷的本地验证路径。测试中用到的嵌入模型为langchain4j-embeddings-all-minilm-l6-v2-q与上文示例代码一致。总结选型建议与注意事项默认开箱即用不显式指定configuration时Store 与 Retriever 均采用 kNN 近似检索适合大多数 RAG 场景精度优先数据量可控、对召回精度要求苛刻时选用ElasticsearchConfigurationScript余弦相似度、精确打分、速度较慢纯文本场景索引中混存了无向量文档或不想引入嵌入模型时选用ElasticsearchConfigurationFullText注意其 BM25 分数未归一化、minScore需重新校准语义 关键词双通道需要同时兼顾语义相关性与关键词精确命中时选用ElasticsearchConfigurationHybrid前提是拥有 Elasticsearch 企业版 License 或试用授权9.2 服务端兼容向量字段默认不再随响应返回除非确有需要否则不要开启includeVectorResponse以免引入兼容性异常与额外带宽开销API 演进方向restClient/serverUrl/apiKey等旧式构建方式均已标记弃用新代码应统一通过ElasticsearchClient接入全文检索请实现新版fullTextSearch(..., FullTextSearchRequest)方法确保maxResults、minScore与filter真正生效。【免费下载链接】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),仅供参考
阅读完成 · 觉得有帮助?
咨询建站