Redis

这一部分将指导您设置RedisVectorStore以存储文档嵌入并执行相似性搜索。

Redis 是什么?

Redis 是一个开源(BSD 许可),用作数据库、缓存、消息代理和流引擎的内存数据结构存储。Redis 提供诸如字符串、哈希、列表、集合、带有范围查询的有序集合、位图、HyperLogLog、地理空间索引和流的数据结构。

Redis 搜索和查询 扩展了 Redis OSS 的核心功能,允许您将 Redis 用作向量数据库:

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

  • 检索向量

  • 执行向量搜索

先决条件

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

    • Transformers Embedding - 在您的本地环境中计算嵌入。请按照 ONNX Transformers Embedding 说明操作。

    • OpenAI Embedding - 使用 OpenAI 嵌入端点。您需要在 OpenAI 注册 并在 API 密钥 生成 API 密钥令牌。

    • 您还可以使用 Azure OpenAI Embedding

  2. 一个 Redis Stack 实例

    1. Redis Cloud(推荐)

    2. Docker 镜像 redis/redis-stack:latest

依赖关系

将以下依赖项添加到您的项目中:

  • 嵌入式客户端启动器,用于计算嵌入式。

  • Transformers Embedding(本地),并按照ONNX Transformers Embedding的说明操作。

<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>
请参阅依赖管理部分,将Spring AI BOM添加到您的构建文件中。

您需要提供您的OpenAI API密钥。请将其设置为环境变量,如下所示:

export SPRING_AI_OPENAI_API_KEY='您的_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>
请参阅依赖管理部分,将Spring AI BOM添加到您的构建文件中。

使用方法

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

@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
  RedisVectorStoreConfig config = RedisVectorStoreConfig.builder()
     .withURI("redis://localhost:6379")
     // 定义用于相似性搜索过滤器的元数据字段。
     .withMetadataFields(
        MetadataField.tag("country"),
        MetadataField.numeric("year"))
     .build();

  return new RedisVectorStore(config, embeddingClient);
}
最方便和首选的方法是将RedisVectorStore创建为Bean。但是,如果您决定手动创建它,则必须在设置属性并在使用客户端之前调用RedisVectorStore#afterPropertiesSet()
您必须明确列出用于过滤器表达式中的任何元数据字段的名称和类型(TAGTEXTNUMERIC)。上面的withMetadataFields注册了可过滤的元数据字段:country类型为TAGyear类型为NUMERIC

然后在您的主代码中,创建一些文档:

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("世界很大,救赎就在拐角处", Map.of()),
   new Document("你向前走,面向过去,你回头朝向未来。", Map.of("country", "NL", "year", 2023)));

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

vectorStore.add(documents);

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

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

如果一切顺利,您应该检索到包含文本“Spring AI rocks!!”的文档。

元数据过滤

您还可以在 RedisVectorStore 中利用通用的、可移植的 元数据过滤器

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

vectorStore.similaritySearch(
   SearchRequest
      .query("The World")
      .withTopK(TOP_K)
      .withSimilarityThreshold(SIMILARITY_THRESHOLD)
      .withFilterExpression("country in ['英国', '荷兰'] && 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", "英国", "荷兰"),
         b.gte("year", 2020)).build()));

可移植的过滤表达式会自动转换为 Redis 搜索查询。例如,以下可移植的过滤表达式:

country in ['英国', '荷兰'] && year >= 2020

转换为 Redis 查询:

@country:{英国 | 荷兰} @year:[2020 inf]