跳到主要内容
版本:2.0.1

Elasticsearch

QWen 3.8 中英对照 Elasticsearch

本节将指导您配置 Elasticsearch VectorStore,以存储文档嵌入并执行相似性搜索。

Elasticsearch 是一个基于 Apache Lucene 库的开源搜索与分析引擎。

前置条件​

正在运行的 Elasticsearch 实例。以下选项可用:

自动配置​

备注

Spring AI 的自动配置(auto-configuration)和 starter 模块的 artifact 名称已发生重大变更。更多信息请参考升级说明。

Spring AI 为 Elasticsearch Vector Store 提供了 Spring Boot 自动配置。若要启用此功能,请将以下依赖项添加到项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中:

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-elasticsearch</artifactId>
</dependency>
备注

对于 spring-boot 3.3.0 之前的版本,必须显式添加版本大于 8.13.3 的 elasticsearch-java 依赖,否则使用的旧版本将与执行的查询不兼容:

<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.13.3</version>
</dependency>
提示

有关在构建文件中添加 Spring AI BOM 的说明,请参阅 Dependency Management 部分。

提示

请参见 Artifact Repositories 部分,将 Maven Central 和/或 Snapshot Repositories 添加到你的构建文件中。

向量存储实现可以为您初始化所需的模式,但您必须通过选择加入来启用此功能,具体方法是在适当的构造函数中指定 initializeSchema 布尔值,或在 application.properties 文件中设置 …​initialize-schema=true。或者,您可以选择不进行初始化,并使用 Elasticsearch 客户端手动创建索引,这在需要高级映射或额外配置时可能非常有用。

备注

这是一个破坏性变更!在 Spring AI 的早期版本中,该 schema 初始化操作默认执行。

请查看配置参数列表,以了解向量存储的默认值和配置选项。这些属性也可以通过配置 ElasticsearchVectorStoreOptions Bean 进行设置。

此外,你还需要一个配置好的 EmbeddingModel bean。更多信息请参见 EmbeddingModel 部分。

现在,你可以将 ElasticsearchVectorStore 自动注入为应用中的向量存储。

@Autowired VectorStore vectorStore;

// ...

List <Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
new Document("The World is Big and Salvation Lurks Around the Corner"),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));

// Add the documents to Elasticsearch
vectorStore.add(documents);

// Retrieve documents similar to a query
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());

配置属性​

要连接 Elasticsearch 并使用 ElasticsearchVectorStore,您需要提供实例的访问详情。简单的配置可以通过 Spring Boot 的 application.yml 提供,

spring:
elasticsearch:
uris: <elasticsearch instance URIs>
username: <elasticsearch username>
password: <elasticsearch password>
ai:
vectorstore:
elasticsearch:
initialize-schema: true
index-name: custom-index
dimensions: 1536
similarity: cosine

以 spring.elasticsearch.* 开头的 Spring Boot 属性用于配置 Elasticsearch 客户端:

属性描述默认值
spring.elasticsearch.connection-timeout与 Elasticsearch 通信时使用的连接超时。1s
spring.elasticsearch.password用于与 Elasticsearch 进行身份验证的密码。-
spring.elasticsearch.username用于与 Elasticsearch 进行身份验证的用户名。-
spring.elasticsearch.uris要使用的 Elasticsearch 实例的逗号分隔列表。http://localhost:9200
spring.elasticsearch.path-prefix添加到发送至 Elasticsearch 的每个请求路径的前缀。-
spring.elasticsearch.restclient.sniffer.delay-after-failure在失败后调度的嗅探执行的延迟时间。1m
spring.elasticsearch.restclient.sniffer.interval连续普通嗅探执行之间的间隔。5m
spring.elasticsearch.restclient.ssl.bundleSSL 绑定名称。-
spring.elasticsearch.socket-keep-alive是否启用客户端与 Elasticsearch 之间的 socket keep alive。false
spring.elasticsearch.socket-timeout与 Elasticsearch 通信时使用的 socket 超时。30s

以 spring.ai.vectorstore.elasticsearch.* 开头的属性用于配置 ElasticsearchVectorStore:

属性描述默认值
spring.ai.vectorstore.elasticsearch.initialize-schema是否初始化所需的 schemafalse
spring.ai.vectorstore.elasticsearch.index-name用于存储向量的索引名称spring-ai-document-index
spring.ai.vectorstore.elasticsearch.dimensions向量的维度数1536
spring.ai.vectorstore.elasticsearch.similarity使用的相似度函数cosine
spring.ai.vectorstore.elasticsearch.embedding-field-name用于搜索的向量字段名称embedding

以下相似度函数可用:

  • cosine - 默认选项,适用于大多数使用场景。衡量向量之间的余弦相似度。

  • l2_norm - 向量之间的欧几里得距离。值越低表示相似度越高。

  • dot_product - 对于归一化向量(例如 OpenAI 嵌入)具有最佳性能。

更多有关密集向量的详细信息,请参见 Elasticsearch 文档中的 Elasticsearch Documentation。

元数据过滤​

你也可以将通用且可移植的 元数据过滤器 应用于 Elasticsearch。

例如,你可以使用文本表达式语言:

vectorStore.similaritySearch(SearchRequest.builder()
.query("The World")
.topK(TOP_K)
.similarityThreshold(SIMILARITY_THRESHOLD)
.filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'").build());

或通过使用 Filter.Expression DSL 以编程方式实现:

FilterExpressionBuilder b = new FilterExpressionBuilder();

vectorStore.similaritySearch(SearchRequest.builder()
.query("The World")
.topK(TOP_K)
.similarityThreshold(SIMILARITY_THRESHOLD)
.filterExpression(b.and(
b.in("author", "john", "jill"),
b.eq("article_type", "blog")).build()).build());
备注

这些(可移植的)过滤表达式会被自动转换为 Elasticsearch 专有的 Query string query。

例如,这个便携式过滤表达式:

author in ['john', 'jill'] && 'article_type' == 'blog'

会转换为 Elasticsearch 的专有过滤器格式:

(metadata.author:john OR jill) AND metadata.article_type:blog

手动配置​

您也可以不使用 Spring Boot 的自动配置,而是手动配置 Elasticsearch 向量存储。为此,您需要在项目中添加 spring-ai-elasticsearch-store 依赖项:

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-elasticsearch-store</artifactId>
</dependency>

或到您的 Gradle build.gradle 构建文件中。

dependencies {
implementation 'org.springframework.ai:spring-ai-elasticsearch-store'
}

创建一个 Elasticsearch Rest5Client Bean。有关配置自定义 Rest5Client 的详细信息,请参阅 Elasticsearch 文档。

@Bean
public Rest5Client restClient() {
return Rest5Client.builder(new HttpHost("<host>", 9200, "http"))
.setDefaultHeaders(new Header[]{
new BasicHeader("Authorization", "Basic <encoded username and password>")
})
.build();
}

然后使用建造者模式创建 ElasticsearchVectorStore Bean:

@Bean
public VectorStore vectorStore(Rest5Client restClient, EmbeddingModel embeddingModel) {
ElasticsearchVectorStoreOptions options = new ElasticsearchVectorStoreOptions();
options.setIndexName("custom-index"); // Optional: defaults to "spring-ai-document-index"
options.setSimilarity(COSINE); // Optional: defaults to COSINE
options.setDimensions(1536); // Optional: defaults to model dimensions or 1536

return ElasticsearchVectorStore.builder(restClient, embeddingModel)
.options(options) // Optional: use custom options
.initializeSchema(true) // Optional: defaults to false
.batchingStrategy(new TokenCountBatchingStrategy()) // Optional: defaults to TokenCountBatchingStrategy
.build();
}

// This can be any EmbeddingModel implementation
@Bean
public EmbeddingModel embeddingModel() {
return new OpenAiEmbeddingModel(OpenAiEmbeddingOptions.builder().apiKey(System.getenv("OPENAI_API_KEY")).build());
}

访问 Native Client​

Elasticsearch 向量存储(Vector Store)实现提供了通过 getNativeClient() 方法访问底层原生 Elasticsearch 客户端(ElasticsearchClient)的功能:

ElasticsearchVectorStore vectorStore = context.getBean(ElasticsearchVectorStore.class);
Optional<ElasticsearchClient> nativeClient = vectorStore.getNativeClient();

if (nativeClient.isPresent()) {
ElasticsearchClient client = nativeClient.get();
// Use the native client for Elasticsearch-specific operations
}

原生客户端为您提供了访问 Elasticsearch 特有功能和操作的能力,而这些内容可能并未通过 VectorStore 接口暴露。