Weaviate

本部分将指导你设置 Weaviate VectorStore,以存储文档嵌入并执行相似性搜索。

What is Weaviate?

Weaviate是一个开源向量数据库。它允许您存储来自您最喜欢的 ML-models 的数据对象和向量嵌入,并无缝扩展到数十亿个数据对象。它提供了存储文档嵌入、内容和元数据以及搜索这些嵌入(包括元数据筛选)的工具。

Prerequisites

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

    • Transformers Embedding - 在本地环境中计算嵌入。遵循 ONNX Transformers 嵌入说明。

    • `OpenAI Embedding`使用 OpenAI 嵌入端点。您需要在 OpenAI Signup上创建一个帐户,并在 API Keys生成 api-key 令牌。

    • 你还可以使用 Azure OpenAI EmbeddingPostgresML Embedding Client

  2. Weaviate cluster。您可以在 Docker 容器中在本地设置集群或创建一个 Weaviate Cloud Service。对于后者,您需要创建一个 Weaviate 帐户,设置一个集群,并从 dashboard details获取您的访问 API 密钥。

在启动时,WeaviateVectorStore 创建所需的 SpringAiWeaviate 对象模式(如果尚未配置)。

Dependencies

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

  • 计算嵌入所需的嵌入客户端启动程序。

  • Transformers 嵌入(本地)并遵循 ONNX Transformers 嵌入说明。

<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>

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

export SPRING_AI_OPENAI_API_KEY='Your_OpenAI_API_Key'
  • 添加 Weaviate VectorStore 依赖项

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-weaviate-store</artifactId>
</dependency>
  1. 参见 Dependency Management 部分,将 Spring AI BOM 添加到你的构建文件中。

Usage

创建一个连接到本地 Weaviate 集群的 WeaviateVectorStore 实例:

@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
  WeaviateVectorStoreConfig config = WeaviateVectorStoreConfig.builder()
     .withScheme("http")
     .withHost("localhost:8080")
     // Define the metadata fields to be used
     // in the similarity search filters.
     .withFilterableMetadataFields(List.of(
        MetadataField.text("country"),
        MetadataField.number("year"),
        MetadataField.bool("active")))
     // Consistency level can be: ONE, QUORUM, or ALL.
     .withConsistencyLevel(ConsistentLevel.ONE)
     .build();

  return new WeaviateVectorStore(config, embeddingClient);
}

对于筛选表达式中使用的任何元数据密钥,必须显式列出所有元数据字段名称和类型(BOOLEANTEXTNUMBER)。上面的 withFilterableMetadataKeys 注册可筛选元数据字段:类型为 TEXTcountry、类型为 NUMBERyear 和类型为 BOOLEANactive

如果可过滤元数据字段通过新条目展开,则必须使用此元数据(重新)上传/更新文档。 您可以在没有明确定义的情况下使用以下 Weaviate system metadata字段:id, _creationTimeUnix, 和 _lastUpdateTimeUnix

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

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", "active", true, "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", "active", false, "year", 2023)));

现在向你的矢量存储添加文档:

vectorStore.add(List.of(document));

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

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

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

Metadata filtering

您还可以将通用、可移植的 metadata filters与 WeaviateVectorStore 一起使用。

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

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()));

便携式过滤表达式会自动转换为专有 Weaviate where filters。例如,以下便携式过滤表达式:

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

将转换为 Weaviate GraphQL where filter expression

operator:And
   operands:
      [{
         operator:Or
         operands:
            [{
               path:["meta_country"]
               operator:Equal
               valueText:"UK"
            },
            {
               path:["meta_country"]
               operator:Equal
               valueText:"NL"
            }]
      },
      {
         path:["meta_year"]
         operator:GreaterThanEqual
         valueNumber:2020
      }]

Run Weaviate cluster in docker container

在 docker 容器中启动 Weaviate:

docker run -it --rm --name weaviate -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true -e PERSISTENCE_DATA_PATH=/var/lib/weaviate -e QUERY_DEFAULTS_LIMIT=25 -e DEFAULT_VECTORIZER_MODULE=none -e CLUSTER_HOSTNAME=node1 -p 8080:8080 semitechnologies/weaviate:1.22.4

使用 [role="bare"][role="bare"]http://localhost:8080/v1 启动一个 Weaviate 集群,其中 scheme=http、host=localhost:8080 且 apiKey=""。然后按照用法说明进行操作。