-
Notifications
You must be signed in to change notification settings - Fork 822
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds GemFireVectorStore Auto-Configuration
- Adds spring boot auto-configuration support for GemFireVectorStore - Adds integration test GemFireVectorStoreAutoConfigurationIT - Includes gemfire-testcontainers in integration tests - Adds unit test GemFireVectorStorePropertiesTests - Refactors GemFireVectorStore.java extracting GemFireVectorStoreConfig.java - Renames spring-ai-gemfire to spring-ai-gemfire-store - Adds GemFireConnectionDetails - Adds GemFireVectorStoreProperties with default values Co-authored-by: Louis Jacome <louis.jacome@broadcom.com> Co-authored-by: Jason Huyn <jason.huynh@broadcom.com>
- Loading branch information
1 parent
2abf10d
commit 8342491
Showing
14 changed files
with
978 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 73 additions & 64 deletions
137
spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/gemfire.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,122 +1,131 @@ | ||
= GemFire Vector Store | ||
|
||
This section walks you through setting up the GemFire VectorStore to store document embeddings and perform similarity searches. | ||
This section walks you through setting up the `GemFireVectorStore` to store document embeddings and perform similarity searches. | ||
|
||
link:https://tanzu.vmware.com/gemfire[GemFire] is an ultra high speed in-memory data and compute grid, with vector extensions to store and search vectors efficiently. | ||
link:https://tanzu.vmware.com/gemfire[GemFire] is a distributed, in-memory, key-value store that performs read and write operations at blazingly fast speeds. It offers highly available parallel message queues, continuous availability, and an event-driven architecture you can scale dynamically with no downtime. As your data size requirements increase to support high-performance, real-time apps, GemFire can scale linearly with ease. | ||
|
||
link:https://docs.vmware.com/en/VMware-GemFire-VectorDB/1.0/gemfire-vectordb/overview.html[GemFire VectorDB] extends GemFire's capabilities, serving as a versatile vector database that efficiently stores, retrieves, and performs vector searches through a distributed and resilient infrastructure: | ||
|
||
Capabilities: | ||
- Create Indexes | ||
- Store vectors and the associated metadata | ||
- Perform vector searches based on similarity | ||
link:https://docs.vmware.com/en/VMware-GemFire-VectorDB/1.0/gemfire-vectordb/overview.html[GemFire VectorDB] extends GemFire's capabilities, serving as a versatile vector database that efficiently stores, retrieves, and performs vector similarity searches. | ||
|
||
== Prerequisites | ||
|
||
Access to a GemFire cluster with the link:https://docs.vmware.com/en/VMware-GemFire-VectorDB/1.0/gemfire-vectordb/install.html[GemFire Vector Database] extension installed. | ||
You can download the GemFire VectorDB extension from the link:https://network.pivotal.io/products/gemfire-vectordb/[VMware Tanzu Network] after signing in. | ||
1. A GemFire cluster with the GemFire VectorDB extension enabled | ||
- link:https://docs.vmware.com/en/VMware-GemFire-VectorDB/1.0/gemfire-vectordb/install.html[Install GemFire VectorDB extension] | ||
|
||
2. An `EmbeddingClient` bean to compute the document embeddings. Refer to the xref:api/embeddings.adoc#available-implementations[EmbeddingClient] section for more information. | ||
|
||
== Dependencies | ||
|
||
Add these dependencies to your project: | ||
=== Maven | ||
|
||
- Embedding Client boot starter, required for calculating embeddings. | ||
- Transformers Embedding (Local) and follow the ONNX Transformers Embedding instructions. | ||
To use just the `GemFireVectorStore`, add the following dependency to your project’s Maven `pom.xml`: | ||
|
||
[source,xml] | ||
[source, xml] | ||
---- | ||
<dependency> | ||
<groupId>org.springframework.ai</groupId> | ||
<artifactId>spring-ai-transformers</artifactId> | ||
<groupId>org.springframework.ai</groupId> | ||
<artifactId>spring-ai-gemfire-store</artifactId> | ||
</dependency> | ||
---- | ||
|
||
- Add the GemFire VectorDB dependencies | ||
To enable Spring Boot’s Auto-Configuration for the `GemFireVectorStore`, also add the following to your project’s Maven `pom.xml`: | ||
|
||
[source,xml] | ||
[source, xml] | ||
---- | ||
<dependency> | ||
<groupId>org.springframework.ai</groupId> | ||
<artifactId>spring-ai-gemfire-store</artifactId> | ||
<artifactId>spring-ai-gemfire-store-spring-boot-starter</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. | ||
=== Gradle | ||
|
||
For Gradle users, add the following to your `build.gradle` file under the dependencies block to use just the `GemFireVectorStore`: | ||
|
||
== Sample Code | ||
[souce, xml] | ||
---- | ||
dependencies { | ||
implementation 'org.springframework.ai:spring-ai-gemfire-store' | ||
} | ||
---- | ||
|
||
- To configure GemFire in your application, use the following setup: | ||
To enable Spring Boot’s Auto-Configuration for the `GemFireVectorStore`, also include this dependency: | ||
|
||
[source,java] | ||
[source, xml] | ||
---- | ||
@Bean | ||
public GemFireVectorStoreConfig gemFireVectorStoreConfig() { | ||
return GemFireVectorStoreConfig.builder() | ||
.withUrl("http://localhost:8080") | ||
.withIndexName("spring-ai-test-index") | ||
.build(); | ||
dependencies { | ||
implementation 'org.springframework.ai:spring-ai-gemfire-store-spring-boot-starter' | ||
} | ||
---- | ||
|
||
- Create a GemFireVectorStore instance connected to your GemFire VectorDB: | ||
== Usage | ||
|
||
- Create a `GemFireVectorStore` instance connected to the GemFire cluster: | ||
|
||
[source,java] | ||
---- | ||
@Bean | ||
public VectorStore vectorStore(GemFireVectorStoreConfig config, EmbeddingClient embeddingClient) { | ||
return new GemFireVectorStore(config, embeddingClient); | ||
public VectorStore vectorStore(EmbeddingClient embeddingClient) { | ||
return new GemFireVectorStore(new GemFireVectorStoreConfig() | ||
.setIndexName("my-vector-index") | ||
.setPort(7071), embeddingClient); | ||
} | ||
---- | ||
- Create a Vector Index which will configure GemFire region. | ||
|
||
[NOTE] | ||
==== | ||
The default configuration connects to a GemFire cluster at `localhost:8080` | ||
==== | ||
|
||
- In your application, create a few documents: | ||
|
||
[source,java] | ||
---- | ||
public void createIndex() { | ||
try { | ||
CreateRequest createRequest = new CreateRequest(); | ||
createRequest.setName(INDEX_NAME); | ||
createRequest.setBeamWidth(20); | ||
createRequest.setMaxConnections(16); | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
String index = objectMapper.writeValueAsString(createRequest); | ||
client.post() | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.bodyValue(index) | ||
.retrieve() | ||
.bodyToMono(Void.class) | ||
.block(); | ||
} | ||
catch (Exception e) { | ||
logger.warn("An unexpected error occurred while creating the index"); | ||
} | ||
} | ||
---- | ||
|
||
- Create some documents: | ||
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))); | ||
---- | ||
|
||
- Add the documents to the vector store: | ||
|
||
[source,java] | ||
---- | ||
List<Document> documents = List.of( | ||
new Document("1", getText("classpath:/test/data/spring.ai.txt"), Map.of("meta1", "meta1")), | ||
new Document("2", getText("classpath:/test/data/time.shelter.txt"), Map.of()), | ||
new Document("3", getText("classpath:/test/data/great.depression.txt"), Map.of("meta2", "meta2"))); | ||
vectorStore.add(documents); | ||
---- | ||
|
||
- Add the documents to GemFire VectorDB: | ||
- And to retrieve documents using similarity search: | ||
|
||
[source,java] | ||
---- | ||
vectorStore.add(List.of(document)); | ||
List<Document> results = vectorStore.similaritySearch( | ||
SearchRequest.query("Spring").withTopK(5)); | ||
---- | ||
|
||
- And finally, retrieve documents similar to a query: | ||
You should retrieve the document containing the text "Spring AI rocks!!". | ||
|
||
You can also limit the number of results using a similarity threshold: | ||
[source,java] | ||
---- | ||
List<Document> results = vectorStore.similaritySearch("Spring", 5); | ||
List<Document> results = vectorStore.similaritySearch( | ||
SearchRequest.query("Spring").withTopK(5) | ||
.withSimilarityThreshold(0.5d)); | ||
---- | ||
|
||
If all goes well, you should retrieve the document containing the text "Spring AI rocks!!". | ||
== GemFireVectorStore properties | ||
|
||
You can use the following properties in your Spring Boot configuration to further configure the `GemFireVectorStore`. | ||
|
||
|=== | ||
|Property|Default value | ||
|
||
|`spring.ai.vectorstore.gemfire.host`|localhost | ||
|`spring.ai.vectorstore.gemfire.port`|8080 | ||
|`spring.ai.vectorstore.gemfire.index-name`|spring-ai-gemfire-store | ||
|`spring.ai.vectorstore.gemfire.beam-width`|100 | ||
|`spring.ai.vectorstore.gemfire.max-connections`|16 | ||
|`spring.ai.vectorstore.gemfire.vector-similarity-function`|COSINE | ||
|`spring.ai.vectorstore.gemfire.fields`|[] | ||
|`spring.ai.vectorstore.gemfire.buckets`|0 | ||
|=== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
...va/org/springframework/ai/autoconfigure/vectorstore/gemfire/GemFireConnectionDetails.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright 2023 - 2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.springframework.ai.autoconfigure.vectorstore.gemfire; | ||
|
||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; | ||
|
||
/** | ||
* @author Geet Rawat | ||
*/ | ||
public interface GemFireConnectionDetails extends ConnectionDetails { | ||
|
||
String getHost(); | ||
|
||
int getPort(); | ||
|
||
} |
84 changes: 84 additions & 0 deletions
84
...ngframework/ai/autoconfigure/vectorstore/gemfire/GemFireVectorStoreAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright 2023-2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.ai.autoconfigure.vectorstore.gemfire; | ||
|
||
import org.springframework.ai.embedding.EmbeddingClient; | ||
import org.springframework.ai.vectorstore.GemFireVectorStore; | ||
import org.springframework.ai.vectorstore.GemFireVectorStoreConfig; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
/** | ||
* @author Geet Rawat | ||
*/ | ||
@AutoConfiguration | ||
@ConditionalOnClass({ GemFireVectorStore.class, EmbeddingClient.class }) | ||
@EnableConfigurationProperties(GemFireVectorStoreProperties.class) | ||
@ConditionalOnProperty(prefix = "spring.ai.vectorstore.gemfire", value = { "index-name" }) | ||
public class GemFireVectorStoreAutoConfiguration { | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(GemFireConnectionDetails.class) | ||
GemFireVectorStoreAutoConfiguration.PropertiesGemFireConnectionDetails gemfireConnectionDetails( | ||
GemFireVectorStoreProperties properties) { | ||
return new GemFireVectorStoreAutoConfiguration.PropertiesGemFireConnectionDetails(properties); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public GemFireVectorStore vectorStore(EmbeddingClient embeddingClient, GemFireVectorStoreProperties properties, | ||
GemFireConnectionDetails gemFireConnectionDetails) { | ||
var config = new GemFireVectorStoreConfig(); | ||
|
||
config.setHost(gemFireConnectionDetails.getHost()) | ||
.setPort(gemFireConnectionDetails.getPort()) | ||
.setIndexName(properties.getIndexName()) | ||
.setBeamWidth(properties.getBeamWidth()) | ||
.setMaxConnections(properties.getMaxConnections()) | ||
.setBuckets(properties.getBuckets()) | ||
.setVectorSimilarityFunction(properties.getVectorSimilarityFunction()) | ||
.setFields(properties.getFields()) | ||
.setSslEnabled(properties.isSslEnabled()); | ||
return new GemFireVectorStore(config, embeddingClient); | ||
} | ||
|
||
private static class PropertiesGemFireConnectionDetails implements GemFireConnectionDetails { | ||
|
||
private final GemFireVectorStoreProperties properties; | ||
|
||
PropertiesGemFireConnectionDetails(GemFireVectorStoreProperties properties) { | ||
|
||
this.properties = properties; | ||
} | ||
|
||
@Override | ||
public String getHost() { | ||
return this.properties.getHost(); | ||
} | ||
|
||
@Override | ||
public int getPort() { | ||
return this.properties.getPort(); | ||
} | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.