Redis

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

本节将指导你设置 RedisVectorStore 用于存储文档嵌入并执行相似性搜索。

Redis 是一个开源(BSD 许可)的内存数据结构存储,用作数据库、缓存、消息代理和流处理引擎。它提供字符串、哈希、列表、集合、有序集合(支持范围查询)、Bitmap、基数统计、地理空间索引和流(Stream)等多种数据结构。

Redis Search and Query 扩展了 Redis 开源版的核心功能,支持将 Redis 用作向量数据库:

  • 在哈希或 JSON 文档中存储向量及关联元数据

  • 检索向量

  • 执行向量搜索

先决条件

  1. Redis Stack 实例

  2. 用于计算文档嵌入的 EmbeddingModel 实例。可选方案包括:

    • 如需生成 RedisVectorStore 存储的嵌入向量,需为 EmbeddingModel 配置 API 密钥。

自动配置

Spring AI 的自动配置及 Starter 模块的构件名称发生重大变更。详情请查阅 升级说明

Spring AI 为 Redis 向量存储提供 Spring Boot 自动配置。要启用该功能,请在项目的 Maven pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-redis</artifactId>
</dependency>

或添加到你的 Gradle build.gradle 构建文件中:

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-vector-store-redis'
}
参考 “依赖管理” 章节将 Spring AI BOM 添加到构建文件中。
参考 构件仓库 章节将 Maven Central 和/或 Snapshot Repositories 添加至构建文件。

向量存储实现可以为你初始化所需 Schema,但你必须通过指定适当构造函数中的 initializeSchema 布尔值或在 application.properties 文件中设置 …​initialize-schema=true 来选择启用。

注意:此为破坏性变更!旧版 Spring AI 中 Schema 初始化默认为自动执行。

请查看向量存储的 配置参数列表 以了解默认值及可配置选项。

此外,还需配置一个 EmbeddingModel Bean。详情请参阅 EmbeddingModel 部分。

现在你可以在应用中自动注入 RedisVectorStore 作为向量存储。

@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 Redis
vectorStore.add(documents);

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

配置属性

要连接 Redis 并使用 RedisVectorStore,需提供实例的访问参数。可通过 Spring Boot 的 application.yml 进行简易配置:

spring:
  data:
    redis:
      url: <redis instance url>
  ai:
    vectorstore:
      redis:
        initialize-schema: true
        index-name: custom-index
        prefix: custom-prefix

Redis 连接配置也可通过 Spring Boot 的 application.properties 文件进行简易设置。

spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.username=default
spring.data.redis.password=

spring.ai.vectorstore.redis.* 开头的属性用于配置 RedisVectorStore

属性 说明 默认值

spring.ai.vectorstore.redis.initialize-schema

是否初始化所需 Schema。

false

spring.ai.vectorstore.redis.index-name

存储向量的索引名称。

spring-ai-index

spring.ai.vectorstore.redis.prefix

Redis Key 的前缀。

embedding:

元数据过滤

你也可以利用 Redis 的通用、可移植 元数据过滤器

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

vectorStore.similaritySearch(SearchRequest.builder()
        .query("The World")
        .topK(TOP_K)
        .similarityThreshold(SIMILARITY_THRESHOLD)
        .filterExpression("country in ['UK', 'NL'] && year >= 2020").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("country", "UK", "NL"),
                b.gte("year", 2020)).build()).build());
这些(可移植的)过滤器表达式会自动转换成 Redis 搜索查询

例如,以下可移植的过滤器表达式:

country in ['UK', 'NL'] && year >= 2020

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

@country:{UK | NL} @year:[2020 inf]

手动配置

若不使用 Spring Boot 自动配置,可手动配置 Redis 向量存储。为此需在项目中添加 spring-ai-redis-store 依赖:

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

或添加到 Gradle build.gradle 构建文件:

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

创建 JedisPooled Bean:

@Bean
public JedisPooled jedisPooled() {
    return new JedisPooled("<host>", 6379);
}

然后使用 Builder 模式创建 RedisVectorStore Bean:

@Bean
public VectorStore vectorStore(JedisPooled jedisPooled, EmbeddingModel embeddingModel) {
    return RedisVectorStore.builder(jedisPooled, embeddingModel)
        .indexName("custom-index")                // Optional: defaults to "spring-ai-index"
        .prefix("custom-prefix")                  // Optional: defaults to "embedding:"
        .metadataFields(                         // Optional: define metadata fields for filtering
            MetadataField.tag("country"),
            MetadataField.numeric("year"))
        .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(new OpenAiApi(System.getenv("OPENAI_API_KEY")));
}

你必须显式列出过滤表达式中使用到的每个元数据字段的名称和类型(TAGTEXTNUMERIC)。上面的 metadataFields 注册了可用于过滤的元数据字段:类型为 TAGcountry,类型为 NUMERICyear

访问原生客户端

Redis 向量存储实现通过 getNativeClient() 方法提供了对底层原生 Redis 客户端(JedisPooled)的访问:

RedisVectorStore vectorStore = context.getBean(RedisVectorStore.class);
Optional<JedisPooled> nativeClient = vectorStore.getNativeClient();

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

原生客户端使你可以访问 VectorStore 接口可能未暴露的、Redis 特有的功能和操作。