主题
OpenSearch
本节引导你设置 OpenSearchVectorStore 以存储文档嵌入并执行相似度搜索。
OpenSearch 是一个最初从 Elasticsearch 分叉而来的开源搜索与分析引擎,以 Apache License 2.0 分发。它通过简化 AI 生成资产的集成与管理来增强 AI 应用开发。OpenSearch 支持向量、词法以及混合搜索能力,利用先进的向量数据库功能来实现低延迟查询与相似度搜索,详见向量数据库页面。
OpenSearch k-NN 功能允许用户从大数据集查询向量嵌入。嵌入是一个数据对象(如文本、图像、音频或文档)的数值表示。嵌入可以存储在索引中,并使用各种相似度函数进行查询。
前置条件
- 一个正在运行的 OpenSearch 实例。有以下可选方案:
- 如有需要,为 EmbeddingModel 配置一个 API 密钥,以生成
OpenSearchVectorStore所存储的嵌入。
自动配置
NOTE
Spring AI 的自动配置、starter 模块的制品名称发生了重大变更。 更多信息请参阅 升级说明。
Spring AI 为 OpenSearch 向量库提供 Spring Boot 自动配置。 要启用它,请将以下依赖添加到你的项目的 Maven pom.xml 文件:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-opensearch</artifactId>
</dependency>或添加到你的 Gradle build.gradle 构建文件:
groovy
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-vector-store-opensearch'
}TIP
无论是自托管还是 Amazon OpenSearch Service,都使用同一个依赖。
参见 依赖管理 一节,把 Spring AI BOM 添加到你的构建文件。
请查看该向量库的配置参数列表,了解默认值和配置选项。
此外,你还需要一个已配置的 EmbeddingModel bean。更多信息参见 EmbeddingModel 一节。
现在你可以在应用中把 OpenSearchVectorStore 作为向量库自动装配:
java
@Autowired VectorStore vectorStore;
// ...
List<Document> documents = List.of(
new Document("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 OpenSearch
vectorStore.add(documents);
// Retrieve documents similar to a query
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());配置属性
要连接到 OpenSearch 并使用 OpenSearchVectorStore,你需要提供实例的访问详情。 一个简单的配置可以通过 Spring Boot 的 application.yml 提供:
yaml
spring:
ai:
vectorstore:
opensearch:
uris: <opensearch instance URIs>
username: <opensearch username>
password: <opensearch password>
index-name: spring-ai-document-index
initialize-schema: true
similarity-function: cosinesimil
read-timeout: <time to wait for response>
connect-timeout: <time to wait until connection established>
path-prefix: <custom path prefix>
ssl-bundle: <name of SSL bundle>
aws: # Only for Amazon OpenSearch Service
host: <aws opensearch host>
service-name: <aws service name>
access-key: <aws access key>
secret-key: <aws secret key>
region: <aws region>以 spring.ai.vectorstore.opensearch.* 开头的属性用于配置 OpenSearchVectorStore:
| 属性 | 描述 | 默认值 |
|---|---|---|
spring.ai.vectorstore.opensearch.uris | OpenSearch 集群端点的 URI | - |
spring.ai.vectorstore.opensearch.username | 访问 OpenSearch 集群的用户名 | - |
spring.ai.vectorstore.opensearch.password | 指定用户名对应的密码 | - |
spring.ai.vectorstore.opensearch.index-name | 存储向量的索引名 | spring-ai-document-index |
spring.ai.vectorstore.opensearch.initialize-schema | 是否初始化所需的模式 | false |
spring.ai.vectorstore.opensearch.similarity-function | 要使用的相似度函数(cosinesimil、l1、l2、linf、innerproduct) | cosinesimil |
spring.ai.vectorstore.opensearch.use-approximate-knn | 是否使用近似 k-NN 以加快搜索。若为 true,使用基于 HNSW 的近似搜索。若为 false,使用精确暴力 k-NN。参见 近似 k-NN 和 精确 k-NN | false |
spring.ai.vectorstore.opensearch.dimensions | 向量嵌入的维度数。在使用近似 k-NN 创建索引映射时使用。若未设置,使用嵌入模型的维度。 | 1536 |
spring.ai.vectorstore.opensearch.mapping-json | 索引的自定义 JSON 映射。覆盖默认的映射生成。 | - |
spring.ai.vectorstore.opensearch.read-timeout | 等待对端响应的时间。0 - 无限。 | - |
spring.ai.vectorstore.opensearch.connect-timeout | 等待建立连接的时间。0 - 无限。 | - |
spring.ai.vectorstore.opensearch.path-prefix | OpenSearch API 端点的路径前缀。当 OpenSearch 位于使用非根路径的反向代理之后时很有用。 | - |
spring.ai.vectorstore.opensearch.ssl-bundle | 在 SSL 连接情况下要使用的 SSL Bundle 名称 | - |
spring.ai.vectorstore.opensearch.aws.host | OpenSearch 实例的主机名 | - |
spring.ai.vectorstore.opensearch.aws.service-name | AWS 服务名 | - |
spring.ai.vectorstore.opensearch.aws.access-key | AWS 访问密钥 | - |
spring.ai.vectorstore.opensearch.aws.secret-key | AWS 私密密钥 | - |
spring.ai.vectorstore.opensearch.aws.region | AWS 区域 | - |
NOTE
你可以使用 spring.ai.vectorstore.opensearch.aws.enabled 属性来控制是否启用 AWS 特定的 OpenSearch 自动配置。
- 若此属性设为
false,则即使 classpath 上存在 AWS SDK 类,也会激活非 AWS 的 OpenSearch 配置。这让你可以在为其他服务而引入了 AWS SDK 的环境中,使用自管理或第三方的 OpenSearch 集群。 - 若不存在 AWS SDK 类,则始终使用非 AWS 配置。
- 若存在 AWS SDK 类且该属性未设置或设为
true,则默认使用 AWS 特定的配置。
这一回退逻辑确保用户对 OpenSearch 集成类型拥有显式控制权,防止在不需要时意外激活 AWS 特定逻辑。
NOTE
path-prefix 属性让你在使用非根路径反向代理之后运行 OpenSearch 时可以指定自定义路径前缀。 例如,如果你的 OpenSearch 实例可访问路径是 https://example.com/opensearch/ 而非 https://example.com/,你就应设置 path-prefix: /opensearch。
以下相似度函数可用:
cosinesimil- 默认,适合大多数用例。衡量向量之间的余弦相似度。l1- 向量之间的曼哈顿距离。l2- 向量之间的欧氏距离。linf- 向量之间的切比雪夫距离。
手动配置
与其使用 Spring Boot 自动配置,不如手动配置 OpenSearch 向量库。为此你需要把 spring-ai-opensearch-store 添加到你的项目:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-opensearch-store</artifactId>
</dependency>或添加到你的 Gradle build.gradle 构建文件:
groovy
dependencies {
implementation 'org.springframework.ai:spring-ai-opensearch-store'
}TIP
参见 依赖管理 一节,把 Spring AI BOM 添加到你的构建文件。
创建一个 OpenSearch 客户端 bean:
java
@Bean
public OpenSearchClient openSearchClient() {
RestClient restClient = RestClient.builder(
HttpHost.create("http://localhost:9200"))
.build();
return new OpenSearchClient(new RestClientTransport(
restClient, new JacksonJsonpMapper()));
}然后使用构建器模式创建 OpenSearchVectorStore bean:
java
@Bean
public VectorStore vectorStore(OpenSearchClient openSearchClient, EmbeddingModel embeddingModel) {
return OpenSearchVectorStore.builder(openSearchClient, embeddingModel)
.index("custom-index") // Optional: defaults to "spring-ai-document-index"
.similarityFunction("l2") // Optional: defaults to "cosinesimil"
.useApproximateKnn(true) // Optional: defaults to false (exact k-NN)
.dimensions(1536) // Optional: defaults to 1536 or embedding model's dimensions
.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());
}元数据过滤
你也可以在 OpenSearch 上利用通用、可移植的元数据过滤器。
例如,你可以使用文本表达式语言:
java
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:
java
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());NOTE
这些(可移植的)过滤表达式会被自动转换为 OpenSearch 专有的 Query string query。
例如,这个可移植的过滤表达式:
sql
author in ['john', 'jill'] && 'article_type' == 'blog'会被转换为 OpenSearch 专有的过滤格式:
(metadata.author:john OR jill) AND metadata.article_type:blog访问原生客户端
OpenSearch 向量库实现通过 getNativeClient() 方法提供对底层原生 OpenSearch 客户端(OpenSearchClient)的访问:
java
OpenSearchVectorStore vectorStore = context.getBean(OpenSearchVectorStore.class);
Optional<OpenSearchClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
OpenSearchClient client = nativeClient.get();
// Use the native client for OpenSearch-specific operations
}原生客户端让你得以访问那些可能未通过 VectorStore 接口暴露的 OpenSearch 特定功能与操作。