Skip to content
LangChain4j 文档版本 1.22.0 源快照 3ed44947 更新于 2026-10-14

Elasticsearch

https://www.elastic.co/

Maven 依赖

xml
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-elasticsearch</artifactId>
    <version>1.22.0-beta32</version>
</dependency>

概述

langchain4j-elasticsearch 模块提供了与 Elasticsearch 的集成,作为嵌入存储与内容检索器。

它带有两个主要类:

两个类都需要一个 Elasticsearch 客户端 来连接到 Elasticsearch 服务器。

java
String apiKey = "VnVhQ2ZHY0JDZGJrU...";
ElasticsearchClient client = ElasticsearchClient.of(ec -> ec
        .host("https://localhost:9200")
        .apiKey(apiKey));

注:

关于如何创建一个 ElasticsearchClient 实例,参见 Elasticsearch 文档。

ElasticsearchEmbeddingStore

要创建 ElasticsearchEmbeddingStore 实例,你需要提供一个 ElasticsearchClient:

java
ElasticsearchEmbeddingStore store = ElasticsearchEmbeddingStore.builder()
    .client(client)
    .build();

它带有以下选项:

  • indexName:要使用的 Elasticsearch 索引名。默认为 default。
  • configuration:要使用的 ElasticsearchConfiguration。默认为 ElasticsearchConfigurationKnn。
  • refresh:由 ID 写入或移除的文档何时对搜索可见。默认为 Refresh.False。

上面的代码等价于:

java
ElasticsearchEmbeddingStore store = ElasticsearchEmbeddingStore.builder()
    .client(client)
    .configuration(ElasticsearchConfigurationKnn.builder().build())
    .indexName("default")
    .build();

刷新策略

Elasticsearch 不会在写请求返回的那一刻就让文档可被搜索。默认情况下,文档会在下一次周期性索引刷新时(每秒一次,除非索引另有设定)对搜索可见。在此之前,文档被安全存储、可按 ID 取回,但不会出现在搜索中。

当你添加文档后紧接着做某种会搜索它们的动作时,这一点就有影响。refresh 选项让你可以改为等待搜索可见性:

java
import co.elastic.clients.elasticsearch._types.Refresh;

ElasticsearchEmbeddingStore store = ElasticsearchEmbeddingStore.builder()
    .client(client)
    .refresh(Refresh.WaitFor)
    .build();

这三个值是:

  • Refresh.False(默认)在文档一被存储就返回,并把刷新留给 Elasticsearch。这是最快的选项。
  • Refresh.WaitFor 在文档对搜索可见后返回。它不强制额外刷新,因此当你需要可见性时,它通常是正确的选择。注意,若索引关闭了自动刷新(index.refresh_interval: -1),该调用会一直等到别的东西触发一次刷新。
  • Refresh.True 立即强制一次刷新。它在不等待的情况下给出可见性,但每次请求都创建一个新段会降低索引吞吐,所以在写密集的索引上应避免它。

该选项适用于 add、addAll 与 removeAll(Collection<String> ids)。它不改变搜索,也不会让你与别人并发做出的写入相隔离。同样的选项在 ElasticsearchContentRetriever.builder() 上也可用。

按过滤条件移除(removeAll(Filter))是一次 delete-by-query,因此它也只匹配那些已对搜索可见的文档:片刻前添加的嵌入可能在它之后仍存活。若你添加嵌入后又立即按过滤条件移除它们,请配置 Refresh.WaitFor,好让写入在移除运行前就可被搜索。

细节参见 Elasticsearch 刷新参数文档。

不带嵌入地存储文档

除了常规的 add(Embedding, TextSegment) 方法,该存储也能为纯文本建索引,而不为它计算嵌入:

java
store.add("Printer troubleshooting guide");                    // generates an id
store.add("my-id", "Printer troubleshooting guide");           // with your own id
store.addAllText(List.of("First guide", "Second guide"));      // several at once

由于这些文档没有向量,向量搜索永不返回它们,无论用 ElasticsearchConfigurationKnn 还是 ElasticsearchConfigurationScript。它们仍会被全文搜索找到,因此单个索引可同时容纳带嵌入与纯文本的文档,你可以用 ElasticsearchConfigurationFullText 或 ElasticsearchConfigurationHybrid 以两种方式搜索它。

ElasticsearchContentRetriever

一个 ContentRetriever 需要一个嵌入模型:

java
EmbeddingModel embeddingModel = new AllMiniLmL6V2QuantizedEmbeddingModel();

要创建一个 ElasticsearchContentRetriever 实例,你需要提供 ElasticsearchClient 与 EmbeddingModel:

java
ElasticsearchContentRetriever contentRetriever = ElasticsearchContentRetriever.builder()
    .client(client)
    .embeddingModel(embeddingModel)
    .build();

它带有以下选项:

  • configuration:要使用的 ElasticsearchConfiguration(见下文)。默认为 ElasticsearchConfigurationKnn。
  • indexName:要使用的 Elasticsearch 索引名。默认为 default。若不存在,索引会被自动创建。
  • maxResults:要检索的最大结果数。默认为 3。
  • minScore:检索结果的最低分数阈值。默认为 0.0。
  • filter:检索期间要应用的 Filter(若有)。默认为 null。

上面的代码等价于:

java
ElasticsearchContentRetriever contentRetriever = ElasticsearchContentRetriever.builder()
    .client(client)
    .embeddingModel(embeddingModel)
    .configuration(ElasticsearchConfigurationKnn.builder().build())
    .indexName("default")
    .maxResults(3)
    .minScore(0.0)
    .filter(null)
    .build();

ElasticsearchConfiguration

一个 ElasticsearchConfiguration 定义了嵌入存储或内容检索器将如何与 Elasticsearch 服务器交互。你可以通过实现 ElasticsearchConfiguration 接口创建你自己的配置,或使用以下提供的某个实现:

要创建一个配置实例,你可以使用每个实现提供的 builder。例如:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationKnn.builder().build();

ElasticsearchConfigurationKnn

ElasticsearchConfigurationKnn 使用近似 kNN 查询来执行向量相似度搜索。

它是 ElasticsearchEmbeddingStore 与 ElasticsearchContentRetriever 都使用的默认配置。

要创建一个实例,你可以使用 builder:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationKnn.builder().build();

它带有以下选项:

  • numCandidates:搜索期间要考虑的候选邻居数。默认为 null,即使用 Elasticsearch 的默认值。
  • includeVectorResponse:是否在搜索响应中包含向量字段。默认为 false。

注: 自 elasticsearch 服务器 9.2 版本起,向量字段默认会从响应中排除。要在响应中包含向量字段(不推荐),请在 builder 中设置 includeVectorResponse:

java
ElasticsearchConfigurationKnn configuration = ElasticsearchConfigurationKnn.builder()
    .includeVectorResponse(true)
    .build();

ElasticsearchConfigurationScript

ElasticsearchConfigurationScript 使用 scriptScore 查询来执行向量相似度搜索。请注意该实现使用余弦相似度。

它对 ElasticsearchEmbeddingStore 与 ElasticsearchContentRetriever 都可用。

要创建一个实例,你可以使用 builder:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationScript.builder().build();

它带有以下选项:

  • includeVectorResponse:是否在搜索响应中包含向量字段。默认为 false。

注: 自 elasticsearch 服务器 9.2 版本起,向量字段默认会从响应中排除。要在响应中包含向量字段(不推荐),请在 builder 中设置 includeVectorResponse:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationScript.builder()
    .includeVectorResponse(true)
    .build();

ElasticsearchConfigurationFullText

ElasticsearchConfigurationFullText 使用全文搜索来检索相关文档。

它仅对 ElasticsearchContentRetriever 可用。

要创建一个实例,你可以使用 builder:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationFullText.builder().build();

ElasticsearchConfigurationHybrid

ElasticsearchConfigurationHybrid 使用混合搜索,把一个 kNN 向量查询与一个全文查询结合。请注意混合搜索需要 elasticsearch 企业许可或试用。

它仅对 ElasticsearchContentRetriever 可用。

要创建一个实例,你可以使用 builder:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationHybrid.builder().build();

它带有以下选项:

  • numCandidates:搜索期间要考虑的候选邻居数。默认为 null,即使用 Elasticsearch 的默认值。
  • includeVectorResponse:是否在搜索响应中包含向量字段。默认为 false。

注: 自 elasticsearch 服务器 9.2 版本起,向量字段默认会从响应中排除。要在响应中包含向量字段(不推荐),请在 builder 中设置 includeVectorResponse:

java
ElasticsearchConfiguration configuration = ElasticsearchConfigurationHybrid.builder()
    .includeVectorResponse(true)
    .build();

创建自定义配置

你可以通过实现 ElasticsearchConfiguration 接口创建你自己的 Elasticsearch 配置。例如:

java
public class MyElasticsearchConfiguration implements ElasticsearchConfiguration {
    @Override
    SearchResponse<Document> vectorSearch(
            ElasticsearchClient client,
            String indexName,
            EmbeddingSearchRequest embeddingSearchRequest) {
        // Your optional custom vector search implementation here
    }

    @Override
    SearchResponse<Document> fullTextSearch(
            ElasticsearchClient client,
            String indexName,
            FullTextSearchRequest request) {
        // Your optional custom full text search implementation here
    }

    @Override
    SearchResponse<Document> hybridSearch(
            ElasticsearchClient client,
            String indexName,
            EmbeddingSearchRequest embeddingSearchRequest,
            String textQuery) {
        // Your optional custom hybrid search implementation here
    }
}

请注意,你可以只实现与你用例相关的那些方法:

  • vectorSearch 用于向量相似度搜索(由 ElasticsearchEmbeddingStore 与 ElasticsearchContentRetriever 共同使用)。
  • fullTextSearch 用于全文搜索(仅由 ElasticsearchContentRetriever 使用)。
  • hybridSearch 用于混合搜索(仅由 ElasticsearchContentRetriever 使用)。

FullTextSearchRequest 携带要搜索的 textQuery,连同在 ElasticsearchContentRetriever 上配置的 maxResults、minScore 与 filter。你的实现负责应用它们,否则不匹配该过滤条件的文档可能被返回。

注: 还有一个已弃用的 fullTextSearch(ElasticsearchClient client, String indexName, String textQuery) 方法。只实现那一个方法的配置仍能继续工作,但检索器的 maxResults、minScore 与 filter 会被忽略,并会记录一条警告。请改实现那个接收 FullTextSearchRequest 的方法。

示例

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。