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:
committed by
Christian Tzolov
parent
25f91c3297
commit
5beef21a4e
@@ -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);
|
||||
}
|
||||
----
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user