Expose QdrantClient and WeaviateClient as beans

Currently, `QdrantClient` and `WeaviateClient` are not exposed as
  beans. Having access to those would benefit to perform operations
  with an already configured client.

  - Deprecate  QdrantVectorStoreConfig.
  - Update Qdrant manual config adoc.
  - Improve Qdrant adoc.
  - Update Weaviate docs.
This commit is contained in:
Eddú Meléndez
2024-05-06 00:21:03 +01:00
committed by Christian Tzolov
parent 25f91c3297
commit 5beef21a4e
7 changed files with 248 additions and 290 deletions

View File

@@ -14,7 +14,7 @@ To set up `QdrantVectorStore`, you'll need the following information from your Q
NOTE: It is recommended that the Qdrant collection is link:https://qdrant.tech/documentation/concepts/collections/#create-a-collection[created] in advance with the appropriate dimensions and configurations.
If the collection is not created, the `QdrantVectorStore` will attempt to create one using the `Cosine` similarity and the dimension of the configured `EmbeddingClient`.
== Dependencies
== Auto-configuration
Then add the Qdrant boot starter dependency to your project:
@@ -96,53 +96,21 @@ vectorStore.add(documents);
List<Document> results = vectorStore.similaritySearch(SearchRequest.query("Spring").withTopK(5));
----
=== Manual Configuration
[[qdrant-vectorstore-properties]]
=== Configuration properties
Instead of using the Spring Boot auto-configuration, you can manually configure the `QdrantVectorStore`. For this you need to add the `spring-ai-qdrant` dependency to your project:
You can use the following properties in your Spring Boot configuration to customize the Qdrant vector store.
[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-qdrant</artifactId>
</dependency>
----
[cols="3,5,1"]
|===
|Property| Description | Default value
or to your Gradle `build.gradle` build file.
[source,groovy]
----
dependencies {
implementation 'org.springframework.ai:spring-ai-qdrant'
}
----
To configure Qdrant in your application, you can use the following setup:
[source,java]
----
@Bean
public QdrantVectorStoreConfig qdrantVectorStoreConfig() {
return QdrantVectorStoreConfig.builder()
.withHost("<QDRANT_HOSTNAME>")
.withPort(<QDRANT_GRPC_PORT>)
.withCollectionName("<QDRANT_COLLECTION_NAME>")
.withApiKey("<QDRANT_API_KEY>")
.build();
}
----
Integrate with OpenAI's embeddings by adding the Spring Boot OpenAI starter to your project.
This provides you with an implementation of the Embeddings client:
[source,java]
----
@Bean
public VectorStore vectorStore(QdrantVectorStoreConfig config, EmbeddingClient embeddingClient) {
return new QdrantVectorStore(config, embeddingClient);
}
----
|`spring.ai.vectorstore.qdrant.host`| The host of the Qdrant server. | localhost
|`spring.ai.vectorstore.qdrant.port`| The gRPC port of the Qdrant server. | 6334
|`spring.ai.vectorstore.qdrant.api-key`| The API key to use for authentication with the Qdrant server. | -
|`spring.ai.vectorstore.qdrant.collection-name`| The name of the collection to use in Qdrant. | -
|`spring.ai.vectorstore.qdrant.use-tls`| Whether to use TLS(HTTPS). | false
|===
== Metadata filtering
@@ -177,18 +145,52 @@ vectorStore.similaritySearch(SearchRequest.defaults()
NOTE: These filter expressions are converted into the equivalent Qdrant link:https://qdrant.tech/documentation/concepts/filtering/[filters].
[[qdrant-vectorstore-properties]]
== Configuration properties
== Manual Configuration
You can use the following properties in your Spring Boot configuration to customize the Qdrant vector store.
Instead of using the Spring Boot auto-configuration, you can manually configure the `QdrantVectorStore`. For this you need to add the `spring-ai-qdrant` dependency to your project:
[cols="3,5,1"]
|===
|Property| Description | Default value
[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-qdrant</artifactId>
</dependency>
----
|`spring.ai.vectorstore.qdrant.host`| The host of the Qdrant server. | localhost
|`spring.ai.vectorstore.qdrant.port`| The gRPC port of the Qdrant server. | 6334
|`spring.ai.vectorstore.qdrant.api-key`| The API key to use for authentication with the Qdrant server. | -
|`spring.ai.vectorstore.qdrant.collection-name`| The name of the collection to use in Qdrant. | -
|`spring.ai.vectorstore.qdrant.use-tls`| Whether to use TLS(HTTPS). | false
|===
or to your Gradle `build.gradle` build file.
[source,groovy]
----
dependencies {
implementation 'org.springframework.ai:spring-ai-qdrant'
}
----
To configure Qdrant in your application, you can create a QdrantClient:
[source,java]
----
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient.Builder grpcClientBuilder =
QdrantGrpcClient.newBuilder(
"<QDRANT_HOSTNAME>",
<QDRANT_GRPC_PORT>,
<IS_TSL>);
grpcClientBuilder.withApiKey("<QDRANT_API_KEY>");
return new QdrantClient(grpcClientBuilder.build());
}
----
Integrate with OpenAI's embeddings by adding the Spring Boot OpenAI starter to your project.
This provides you with an implementation of the Embeddings client:
[source,java]
----
@Bean
public QdrantVectorStore vectorStore(EmbeddingClient embeddingClient, QdrantClient qdrantClient) {
return new QdrantVectorStore(qdrantClient, "<QDRANT_COLLECTION_NAME>", embeddingClient);
}
----

View File

@@ -19,115 +19,106 @@ It provides tools to store document embeddings, content, and metadata and to sea
On startup, the `WeaviateVectorStore` creates the required `SpringAiWeaviate` object schema if it's not already provisioned.
== Dependencies
== Auto-configuration
Add these dependencies to your project:
* Embedding Client boot starter, required for calculating embeddings.
* Transformers Embedding (Local) and follow the ONNX Transformers Embedding instructions.
Then add the WeaviateVectorStore boot starter dependency to your project:
[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-transformers-spring-boot-starter</artifactId>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-weaviate-store-spring-boot-starter</artifactId>
</dependency>
----
or use OpenAI (Cloud)
or to your Gradle `build.gradle` build file.
[source,xml]
[source,groovy]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
----
You'll need to provide your OpenAI API Key. Set it as an environment variable like so:
[source,bash]
----
export SPRING_AI_OPENAI_API_KEY='Your_OpenAI_API_Key'
----
* Add the Weaviate VectorStore dependency
[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-weaviate-store</artifactId>
</dependency>
----
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
== Usage
Create a WeaviateVectorStore instance connected to the local Weaviate cluster:
[source,java]
----
@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);
dependencies {
implementation 'org.springframework.ai:spring-ai-weaviate-store-spring-boot-starter'
}
----
> [NOTE]
> You must list explicitly all metadata field names and types (`BOOLEAN`, `TEXT`, or `NUMBER`) for any metadata key used in filter expression.
> The `withFilterableMetadataKeys` above registers filterable metadata fields: `country` of type `TEXT`, `year` of type `NUMBER`, and `active` of type `BOOLEAN`.
>
> If the filterable metadata fields are expanded with new entries, you have to (re)upload/update the documents with this metadata.
>
> You can use the following Weaviate link:https://weaviate.io/developers/weaviate/api/graphql/filters#special-cases[system metadata] fields without explicit definition: `id`, `_creationTimeUnix`, and `_lastUpdateTimeUnix`.
The Vector Store, also requires an `EmbeddingClient` instance to calculate embeddings for the documents.
You can pick one of the available xref:api/embeddings.adoc#available-implementations[EmbeddingClient Implementations].
Then in your main code, create some documents:
For example to use the xref:api/embeddings/openai-embeddings.adoc[OpenAI EmbeddingClient] add the following dependency to your project:
[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
----
or to your Gradle `build.gradle` build file.
[source,groovy]
----
dependencies {
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
}
----
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
Refer to the xref:getting-started.adoc#repositories[Repositories] section to add Milestone and/or Snapshot Repositories to your build file.
To connect to Weaviate and use the `WeaviateVectorStore`, you need to provide access details for your instance.
A simple configuration can either be provided via Spring Boot's _application.properties_,
[source,properties]
----
spring.ai.vectorstore.weaviate.host=<host of your Weaviate instance>
spring.ai.vectorstore.weaviate.api-key=<your api key>
spring.ai.vectorstore.weaviate.scheme=http
# API key if needed, e.g. OpenAI
spring.ai.openai.api.key=<api-key>
----
TIP: Check the list of xref:#weaviate-vectorstore-properties[configuration parameters] to learn about the default values and configuration options.
Now you can Auto-wire the Weaviate Vector Store in your application and use it
[source,java]
----
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)));
@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
vectorStore.add(documents);
// Retrieve documents similar to a query
List<Document> results = vectorStore.similaritySearch(SearchRequest.query("Spring").withTopK(5));
----
Now add the documents to your vector store:
[[weaviate-vectorstore-properties]]
=== Configuration properties
You can use the following properties in your Spring Boot configuration to customize the weaviate vector store.
[source,java]
----
vectorStore.add(List.of(document));
----
[cols="3,5,1"]
|===
|Property| Description | Default value
And finally, retrieve documents similar to a query:
|`spring.ai.vectorstore.weaviate.host`| The host of the Weaviate server. | localhost:8080
|`spring.ai.vectorstore.weaviate.scheme`| Connection schema. | http
|`spring.ai.vectorstore.weaviate.api-key`| The API key to use for authentication with the Weaviate server. | -
|`spring.ai.vectorstore.weaviate.object-class`| | "SpringAiWeaviate"
|`spring.ai.vectorstore.weaviate.consistency-level`| Desired tradeoff between consistency and speed | ConsistentLevel.ONE
|`spring.ai.vectorstore.weaviate.filter-field`| spring.ai.vectorstore.weaviate.filter-field.<field-name>=<field-type> | -
|`spring.ai.vectorstore.weaviate.headers`| | -
|===
[source,java]
----
List<Document> results = vectorStore.similaritySearch(
SearchRequest
.query("Spring")
.withTopK(5));
----
If all goes well, you should retrieve the document containing the text "Spring AI rocks!!".
=== Metadata filtering
== Metadata filtering
You can leverage the generic, portable link:https://docs.spring.io/spring-ai/reference/api/vectordbs.html#_metadata_filters[metadata filters] with WeaviateVectorStore as well.
@@ -194,6 +185,61 @@ operator:And
}]
----
== Manual Configuration
Instead of using the Spring Boot auto-configuration, you can manually configure the `WeaviateVectorStore`.
For this you need to add the `spring-ai-weaviate-store` dependency to your project:
[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-weaviate-store</artifactId>
</dependency>
----
or to your Gradle `build.gradle` build file.
[source,groovy]
----
dependencies {
implementation 'org.springframework.ai:spring-ai-weaviate-store'
}
----
To configure Weaviate in your application, you can create a WeaviateClient:
[source,java]
----
@Bean
public WeaviateClient weaviateClient() {
try {
return WeaviateAuthClient.apiKey(
new Config(<YOUR SCHEME>, <YOUR HOST>, <YOUR HEADERS>),
<YOUR API KEY>);
}
catch (AuthException e) {
throw new IllegalArgumentException("WeaviateClient could not be created.", e);
}
}
----
Integrate with OpenAI's embeddings by adding the Spring Boot OpenAI starter to your project.
This provides you with an implementation of the Embeddings client:
[source,java]
----
@Bean
public WeaviateVectorStore vectorStore(EmbeddingClient embeddingClient, WeaviateClient weaviateClient) {
WeaviateVectorStoreConfig.Builder configBuilder = WeaviateVectorStore.WeaviateVectorStoreConfig.builder()
.withObjectClass(<YOUR OBJECT CLASS>)
.withConsistencyLevel(<YOUR CONSISTENCY LEVEL>);
return new WeaviateVectorStore(configBuilder.build(), embeddingClient, weaviateClient);
}
----
== Run Weaviate cluster in docker container
Start Weaviate in a docker container:

View File

@@ -15,9 +15,10 @@
*/
package org.springframework.ai.autoconfigure.vectorstore.qdrant;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore.QdrantVectorStoreConfig;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -42,21 +43,25 @@ public class QdrantVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public QdrantVectorStore vectorStore(EmbeddingClient embeddingClient, QdrantVectorStoreProperties properties,
public QdrantClient qdrantClient(QdrantVectorStoreProperties properties,
QdrantConnectionDetails connectionDetails) {
QdrantGrpcClient.Builder grpcClientBuilder = QdrantGrpcClient.newBuilder(connectionDetails.getHost(),
connectionDetails.getPort(), properties.isUseTls());
var config = QdrantVectorStoreConfig.builder()
.withCollectionName(properties.getCollectionName())
.withHost(connectionDetails.getHost())
.withPort(connectionDetails.getPort())
.withTls(properties.isUseTls())
.withApiKey(properties.getApiKey())
.build();
return new QdrantVectorStore(config, embeddingClient);
if (properties.getApiKey() != null) {
grpcClientBuilder.withApiKey(properties.getApiKey());
}
return new QdrantClient(grpcClientBuilder.build());
}
private static class PropertiesQdrantConnectionDetails implements QdrantConnectionDetails {
@Bean
@ConditionalOnMissingBean
public QdrantVectorStore vectorStore(EmbeddingClient embeddingClient, QdrantVectorStoreProperties properties,
QdrantClient qdrantClient) {
return new QdrantVectorStore(qdrantClient, properties.getCollectionName(), embeddingClient);
}
static class PropertiesQdrantConnectionDetails implements QdrantConnectionDetails {
private final QdrantVectorStoreProperties properties;

View File

@@ -15,6 +15,10 @@
*/
package org.springframework.ai.autoconfigure.vectorstore.weaviate;
import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;
import io.weaviate.client.WeaviateClient;
import io.weaviate.client.v1.auth.exception.AuthException;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.WeaviateVectorStore;
import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig;
@@ -42,14 +46,24 @@ public class WeaviateVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public WeaviateVectorStore vectorStore(EmbeddingClient embeddingClient, WeaviateVectorStoreProperties properties,
public WeaviateClient weaviateClient(WeaviateVectorStoreProperties properties,
WeaviateConnectionDetails connectionDetails) {
try {
return WeaviateAuthClient.apiKey(
new Config(properties.getScheme(), connectionDetails.getHost(), properties.getHeaders()),
properties.getApiKey());
}
catch (AuthException e) {
throw new IllegalArgumentException("WeaviateClient could not be created.", e);
}
}
@Bean
@ConditionalOnMissingBean
public WeaviateVectorStore vectorStore(EmbeddingClient embeddingClient, WeaviateClient weaviateClient,
WeaviateVectorStoreProperties properties) {
WeaviateVectorStoreConfig.Builder configBuilder = WeaviateVectorStore.WeaviateVectorStoreConfig.builder()
.withScheme(properties.getScheme())
.withApiKey(properties.getApiKey())
.withHost(connectionDetails.getHost())
.withHeaders(properties.getHeaders())
.withObjectClass(properties.getObjectClass())
.withFilterableMetadataFields(properties.getFilterField()
.entrySet()
@@ -58,10 +72,10 @@ public class WeaviateVectorStoreAutoConfiguration {
.toList())
.withConsistencyLevel(properties.getConsistencyLevel());
return new WeaviateVectorStore(configBuilder.build(), embeddingClient);
return new WeaviateVectorStore(configBuilder.build(), embeddingClient, weaviateClient);
}
private static class PropertiesWeaviateConnectionDetails implements WeaviateConnectionDetails {
static class PropertiesWeaviateConnectionDetails implements WeaviateConnectionDetails {
private final WeaviateVectorStoreProperties properties;

View File

@@ -34,7 +34,6 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.JsonWithInt.Value;
@@ -51,6 +50,7 @@ import io.qdrant.client.grpc.Points.UpdateStatus;
*
* @author Anush Shetty
* @author Christian Tzolov
* @author Eddú Meléndez
* @since 0.8.1
*/
public class QdrantVectorStore implements VectorStore, InitializingBean {
@@ -69,13 +69,14 @@ public class QdrantVectorStore implements VectorStore, InitializingBean {
/**
* Configuration class for the QdrantVectorStore.
*
* @deprecated since 1.0.0 in favor of {@link QdrantVectorStore}.
*/
@Deprecated(since = "1.0.0", forRemoval = true)
public static final class QdrantVectorStoreConfig {
private final String collectionName;
private QdrantClient qdrantClient;
/*
* Constructor using the builder.
*
@@ -83,15 +84,6 @@ public class QdrantVectorStore implements VectorStore, InitializingBean {
*/
private QdrantVectorStoreConfig(Builder builder) {
this.collectionName = builder.collectionName;
QdrantGrpcClient.Builder grpcClientBuilder = QdrantGrpcClient.newBuilder(builder.host, builder.port,
builder.useTls);
if (builder.apiKey != null) {
grpcClientBuilder.withApiKey(builder.apiKey);
}
this.qdrantClient = new QdrantClient(grpcClientBuilder.build());
}
/**
@@ -113,26 +105,9 @@ public class QdrantVectorStore implements VectorStore, InitializingBean {
private String collectionName;
private String host = "localhost";
private int port = 6334;
private boolean useTls = false;
private String apiKey = null;
private Builder() {
}
/**
* @param host The host of the Qdrant instance. Defaults to "localhost".
*/
public Builder withHost(String host) {
Assert.notNull(host, "host cannot be null");
this.host = host;
return this;
}
/**
* @param collectionName REQUIRED. The name of the collection.
*/
@@ -141,32 +116,6 @@ public class QdrantVectorStore implements VectorStore, InitializingBean {
return this;
}
/**
* @param port The GRPC port of the Qdrant instance. Defaults to 6334.
* @return
*/
public Builder withPort(int port) {
this.port = port;
return this;
}
/**
* @param useTls Whether to use TLS(HTTPS). Defaults to false.
* @return
*/
public Builder withTls(boolean useTls) {
this.useTls = useTls;
return this;
}
/**
* @param apiKey The Qdrant API key to authenticate with. Defaults to null.
*/
public Builder withApiKey(String apiKey) {
this.apiKey = apiKey;
return this;
}
/**
* {@return the immutable configuration}
*/
@@ -183,9 +132,12 @@ public class QdrantVectorStore implements VectorStore, InitializingBean {
* Constructs a new QdrantVectorStore.
* @param config The configuration for the store.
* @param embeddingClient The client for embedding operations.
* @deprecated since 1.0.0 in favor of {@link QdrantVectorStore}.
*/
public QdrantVectorStore(QdrantVectorStoreConfig config, EmbeddingClient embeddingClient) {
this(config.qdrantClient, config.collectionName, embeddingClient);
@Deprecated(since = "1.0.0", forRemoval = true)
public QdrantVectorStore(QdrantClient qdrantClient, QdrantVectorStoreConfig config,
EmbeddingClient embeddingClient) {
this(qdrantClient, config.collectionName, embeddingClient);
}
/**

View File

@@ -25,12 +25,9 @@ import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;
import io.weaviate.client.WeaviateClient;
import io.weaviate.client.base.Result;
import io.weaviate.client.base.WeaviateErrorMessage;
import io.weaviate.client.v1.auth.exception.AuthException;
import io.weaviate.client.v1.batch.model.BatchDeleteResponse;
import io.weaviate.client.v1.batch.model.ObjectGetResponse;
import io.weaviate.client.v1.data.model.WeaviateObject;
@@ -63,6 +60,7 @@ import org.springframework.util.StringUtils;
* expression filters.
*
* @author Christian Tzolov
* @author Eddú Meléndez
*/
public class WeaviateVectorStore implements VectorStore, InitializingBean {
@@ -169,18 +167,6 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
}
/**
* The server api key.
*/
private final String apiKey;
/**
* The URL scheme, such as 'http' or 'https'.
*/
private final String scheme;
private final String host;
private final String weaviateObjectClass;
private final ConsistentLevel consistencyLevel;
@@ -199,9 +185,6 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
* @param builder The configuration builder.
*/
public WeaviateVectorStoreConfig(Builder builder) {
this.apiKey = builder.apiKey;
this.scheme = builder.scheme;
this.host = builder.host;
this.weaviateObjectClass = builder.objectClass;
this.consistencyLevel = builder.consistencyLevel;
this.filterMetadataFields = builder.filterMetadataFields;
@@ -225,12 +208,6 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
public static class Builder {
private String apiKey = "";
private String scheme = "http";
private String host = "localhost:8080";
private String objectClass = "SpringAiWeaviate";
private ConsistentLevel consistencyLevel = WeaviateVectorStoreConfig.ConsistentLevel.ONE;
@@ -242,39 +219,6 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
private Builder() {
}
/**
* Weaviate api key.
* @param apiKey key to use.
* @return this builder.
*/
public Builder withApiKey(String apiKey) {
Assert.notNull(apiKey, "The apiKey can not be null.");
this.apiKey = apiKey;
return this;
}
/**
* Weaviate scheme.
* @param scheme scheme to use.
* @return this builder.
*/
public Builder withScheme(String scheme) {
Assert.hasText(scheme, "The scheme can not be empty.");
this.scheme = scheme;
return this;
}
/**
* Weaviate host.
* @param host host to use.
* @return this builder.
*/
public Builder withHost(String host) {
Assert.hasText(host, "The host can not be empty.");
this.host = host;
return this;
}
/**
* Weaviate known, filterable metadata fields.
* @param filterMetadataFields known metadata fields to use.
@@ -335,7 +279,8 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
* @param vectorStoreConfig The configuration for the store.
* @param embeddingClient The client for embedding operations.
*/
public WeaviateVectorStore(WeaviateVectorStoreConfig vectorStoreConfig, EmbeddingClient embeddingClient) {
public WeaviateVectorStore(WeaviateVectorStoreConfig vectorStoreConfig, EmbeddingClient embeddingClient,
WeaviateClient weaviateClient) {
Assert.notNull(vectorStoreConfig, "WeaviateVectorStoreConfig must not be null");
Assert.notNull(embeddingClient, "EmbeddingClient must not be null");
@@ -345,16 +290,7 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
this.filterMetadataFields = vectorStoreConfig.filterMetadataFields;
this.filterExpressionConverter = new WeaviateFilterExpressionConverter(
this.filterMetadataFields.stream().map(MetadataField::name).toList());
try {
this.weaviateClient = WeaviateAuthClient.apiKey(
new Config(vectorStoreConfig.scheme, vectorStoreConfig.host, vectorStoreConfig.headers),
vectorStoreConfig.apiKey);
}
catch (AuthException e) {
throw new IllegalArgumentException(e);
}
this.weaviateClient = weaviateClient;
this.weaviateSimilaritySearchFields = buildWeaviateSimilaritySearchFields();
}

View File

@@ -22,6 +22,8 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import io.weaviate.client.Config;
import io.weaviate.client.WeaviateClient;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -242,14 +244,15 @@ public class WeaviateVectorStoreIT {
@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
WeaviateClient weaviateClient = new WeaviateClient(
new Config("http", weaviateContainer.getHttpHostAddress()));
WeaviateVectorStoreConfig config = WeaviateVectorStore.WeaviateVectorStoreConfig.builder()
.withScheme("http")
.withHost(weaviateContainer.getHttpHostAddress())
.withFilterableMetadataFields(List.of(MetadataField.text("country"), MetadataField.number("year")))
.withConsistencyLevel(WeaviateVectorStoreConfig.ConsistentLevel.ONE)
.build();
WeaviateVectorStore vectorStore = new WeaviateVectorStore(config, embeddingClient);
WeaviateVectorStore vectorStore = new WeaviateVectorStore(config, embeddingClient, weaviateClient);
return vectorStore;
}