本节将引导您设置`RedisVectorStore`以存储文档嵌入并执行相似性搜索。

Redis是什么?

链接:https://redis.io[Redis] 是一个开源的(BSD许可),内存中的数据结构存储,用作数据库、缓存、消息代理和流处理引擎。Redis 提供了如字符串、哈希、列表、集合、有序集合以范围查询、位图、超日志、地理空间索引和流等数据结构。

Redis Vector Search是什么?

链接:https://redis.io/docs/interact/search-and-query/[Redis 搜索和查询] 扩展了 Redis OSS 的核心功能,允许你将 Redis 用作向量数据库:

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

  • 检索向量

  • 执行向量搜索

前提条件

  1. 使用`EmbeddingClient`实例来计算文档嵌入。有几种可用的选项:

    • Transformers Embedding` - 在你的本地环境中计算嵌入。请按照ONNX Transformers嵌入的指示操作。

    • OpenAI Embedding` - 使用OpenAI嵌入端点。你需要在链接:https://platform.openai.com/signup[OpenAI 注册]创建一个帐户,并在链接:https://platform.openai.com/account/api-keys[API 密钥]生成api-key 令牌。

    • 你也可以使用`Azure OpenAI Embedding`。

  2. 一个Redis Stack实例

    1. Redis Cloud (推荐)

    2. 链接:https://hub.docker.com/r/redis/redis-stack[Docker] 镜像 redis/redis-stack:latest

依赖项

将这些依赖项添加到您的项目中:

  • 嵌入式客户端启动器,计算嵌入式所需。

  • 变换器嵌入(本地)并遵循 ONNX 变换器嵌入指南。

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-transformers-spring-boot-starter</artifactId>
</dependency>

或者使用OpenAI(云端)

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
Tip
参考依赖管理章节,将Spring AI BOM添加到构建文件中。

你需要提供你的OpenAI API密钥。像这样设置为环境变量:

export SPRING_AI_OPENAI_API_KEY='Your_OpenAI_API_Key'
  • 添加Redis Vector Store和Jedis依赖

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

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.1.0</version>
</dependency>
Tip
参考依赖管理章节,将Spring AI BOM添加到构建文件中。

使用方法

创建一个连接到你的Redis数据库的RedisVectorStore实例:

@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
  RedisVectorStoreConfig config = RedisVectorStoreConfig.builder()
     .withURI("redis://localhost:6379")
     // Define the metadata fields to be used
     // in the similarity search filters.
     .withMetadataFields(
        MetadataField.tag("country"),
        MetadataField.numeric("year"))
     .build();

return new RedisVectorStore(config, embeddingClient);
}

将`RedisVectorStore`创建为Bean更加方便和受欢迎。 但是,如果您决定手动创建它,那么在设置属性并在使用客户端之前,您必须调用 RedisVectorStore#afterPropertiesSet() 方法。

你必须明确列出在过滤表达式中使用的所有元数据字段的名称和类型(TAGTEXTNUMERIC)。 上述的 withMetadataFields 用于注册可筛选的元数据字段:类型为 TAGcountry,类型为 NUMERICyear

那么在你的主代码中,创建一些文档:

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

现在将文档添加到你的向量存储中:

vectorStore.add(documents);

最后,检索与查询相似的文档:

List<Document> results = vectorStore.similaritySearch(
   SearchRequest
      .query("Spring")
      .withTopK(5));

如果一切顺利,你应该会找回包含文本“Spring AI rocks!!”的文档。

元数据过滤

您也可以利用通用的、可移植的链接:https://docs.spring.io/spring-ai/reference/api/vectordbs.html#_metadata_filters【元数据过滤器】搭配 RedisVectorStore 使用。

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

vectorStore.similaritySearch(
   SearchRequest
      .query("The World")
      .withTopK(TOP_K)
      .withSimilarityThreshold(SIMILARITY_THRESHOLD)
      .withFilterExpression("country in ['UK', 'NL'] && year >= 2020"));

或者通过表达式DSL来编程实现:

FilterExpressionBuilder b = new FilterExpressionBuilder();

vectorStore.similaritySearch(
   SearchRequest
      .query("The World")
      .withTopK(TOP_K)
      .withSimilarityThreshold(SIMILARITY_THRESHOLD)
      .withFilterExpression(b.and(
         b.in("country", "UK", "NL"),
         b.gte("year", 2020)).build()));

便携式过滤表达式会自动转换成链接:https://redis.io/docs/interact/search-and-query/query/[Redis搜索查询]。例如,以下的便携式过滤表达式:

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

转换为Redis查询:

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