Unify the vector store module and pom names
spring-ai-qdrant -> spring-ai-qdrant-store spring-ai-cassandra -> spring-ai-cassandra-store spring-ai-pinecone -> spring-ai-pinecone-store spring-ai-redis -> spring-ai-redis-store spring-ai-qdrant -> spring-ai-qdrant-store spring-ai-gemfire -> spring-ai-gemfire-store spring-ai-azure-vector-store-spring-boot-starter -> spring-ai-azure-store-spring-boot-starter spring-ai-redis-spring-boot-starter -> spring-ai-redis-store-spring-boot-starter
This commit is contained in:
@@ -77,7 +77,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
||||
106
pom.xml
106
pom.xml
@@ -13,67 +13,73 @@
|
||||
<description>Building AI applications with Spring Boot</description>
|
||||
|
||||
<modules>
|
||||
<module>spring-ai-docs</module>
|
||||
<module>spring-ai-bom</module>
|
||||
<module>spring-ai-core</module>
|
||||
<module>models/spring-ai-transformers</module>
|
||||
<module>models/spring-ai-postgresml</module>
|
||||
<module>models/spring-ai-bedrock</module>
|
||||
<module>models/spring-ai-azure-openai</module>
|
||||
<module>models/spring-ai-huggingface</module>
|
||||
<module>models/spring-ai-ollama</module>
|
||||
<module>models/spring-ai-openai</module>
|
||||
<module>models/spring-ai-stability-ai</module>
|
||||
<module>models/spring-ai-mistral-ai</module>
|
||||
<module>models/spring-ai-vertex-ai-palm2</module>
|
||||
<module>models/spring-ai-vertex-ai-gemini</module>
|
||||
<module>models/spring-ai-anthropic</module>
|
||||
<module>models/spring-ai-watsonx-ai</module>
|
||||
<module>spring-ai-test</module>
|
||||
<module>spring-ai-spring-boot-autoconfigure</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-openai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-azure-openai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-ollama</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-transformers</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-cassandra</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-chroma-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-milvus-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-pgvector-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-hanadb-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-pinecone-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-azure-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-weaviate-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-redis</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-stability-ai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-neo4j-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-qdrant-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-postgresml-embedding</module>
|
||||
<module>spring-ai-docs</module>
|
||||
<module>vector-stores/spring-ai-cassandra</module>
|
||||
<module>vector-stores/spring-ai-pgvector-store</module>
|
||||
<module>vector-stores/spring-ai-hanadb-store</module>
|
||||
<module>vector-stores/spring-ai-milvus-store</module>
|
||||
<module>vector-stores/spring-ai-neo4j-store</module>
|
||||
<module>spring-ai-retry</module>
|
||||
<module>spring-ai-spring-boot-testcontainers</module>
|
||||
|
||||
<module>document-readers/pdf-reader</module>
|
||||
<module>document-readers/tika-reader</module>
|
||||
<module>vector-stores/spring-ai-pinecone</module>
|
||||
<module>vector-stores/spring-ai-chroma-store</module>
|
||||
|
||||
<module>vector-stores/spring-ai-azure-store</module>
|
||||
<module>vector-stores/spring-ai-cassandra-store</module>
|
||||
<module>vector-stores/spring-ai-chroma-store</module>
|
||||
<module>vector-stores/spring-ai-elasticsearch-store</module>
|
||||
<module>vector-stores/spring-ai-gemfire-store</module>
|
||||
<module>vector-stores/spring-ai-hanadb-store</module>
|
||||
<module>vector-stores/spring-ai-milvus-store</module>
|
||||
<module>vector-stores/spring-ai-mongodb-atlas-store</module>
|
||||
<module>vector-stores/spring-ai-neo4j-store</module>
|
||||
<module>vector-stores/spring-ai-pgvector-store</module>
|
||||
<module>vector-stores/spring-ai-pinecone-store</module>
|
||||
<module>vector-stores/spring-ai-qdrant-store</module>
|
||||
<module>vector-stores/spring-ai-redis-store</module>
|
||||
<module>vector-stores/spring-ai-weaviate-store</module>
|
||||
<module>vector-stores/spring-ai-redis</module>
|
||||
<module>vector-stores/spring-ai-gemfire</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-palm2</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-gemini</module>
|
||||
<module>vector-stores/spring-ai-qdrant</module>
|
||||
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-azure-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-cassandra-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-chroma-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-elasticsearch-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-hanadb-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-milvus-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-mongodb-atlas-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-neo4j-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-pgvector-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-pinecone-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-qdrant-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-redis-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-weaviate-store</module>
|
||||
|
||||
<module>models/spring-ai-anthropic</module>
|
||||
<module>models/spring-ai-azure-openai</module>
|
||||
<module>models/spring-ai-bedrock</module>
|
||||
<module>models/spring-ai-huggingface</module>
|
||||
<module>models/spring-ai-mistral-ai</module>
|
||||
<module>models/spring-ai-ollama</module>
|
||||
<module>models/spring-ai-openai</module>
|
||||
<module>models/spring-ai-postgresml</module>
|
||||
<module>models/spring-ai-stability-ai</module>
|
||||
<module>models/spring-ai-transformers</module>
|
||||
<module>models/spring-ai-vertex-ai-gemini</module>
|
||||
<module>models/spring-ai-vertex-ai-palm2</module>
|
||||
<module>models/spring-ai-watsonx-ai</module>
|
||||
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-anthropic</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-azure-openai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-bedrock-ai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-mistral-ai</module>
|
||||
<module>spring-ai-retry</module>
|
||||
<module>vector-stores/spring-ai-mongodb-atlas-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-mongodb-atlas-store</module>
|
||||
<module>spring-ai-spring-boot-testcontainers</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-anthropic</module>
|
||||
<module>vector-stores/spring-ai-elasticsearch-store</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-ollama</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-openai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-postgresml-embedding</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-stability-ai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-transformers</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-gemini</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-palm2</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-watsonx-ai</module>
|
||||
<module>spring-ai-spring-boot-starters/spring-ai-starter-elasticsearch-store</module>
|
||||
|
||||
</modules>
|
||||
|
||||
<organization>
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-cassandra</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -170,13 +170,13 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-pinecone</artifactId>
|
||||
<artifactId>spring-ai-pinecone-store</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-redis</artifactId>
|
||||
<artifactId>spring-ai-redis-store</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-gemfire</artifactId>
|
||||
<artifactId>spring-ai-gemfire-store</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-azure-vector-store-spring-boot-starter</artifactId>
|
||||
<artifactId>spring-ai-azure-store-spring-boot-starter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -316,7 +316,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-redis-spring-boot-starter</artifactId>
|
||||
<artifactId>spring-ai-redis-store-spring-boot-starter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ Add these dependencies to your project:
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-cassandra</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
@@ -67,7 +67,7 @@ Add these dependencies to your project:
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-cassandra-spring-boot-starter</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Add these dependencies to your project:
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-gemfire</artifactId>
|
||||
<artifactId>spring-ai-gemfire-store</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ Add these dependencies to your project:
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-pinecone</artifactId>
|
||||
<artifactId>spring-ai-pinecone-store</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
|
||||
@@ -147,13 +147,13 @@ NOTE: These filter expressions are converted into the equivalent Qdrant link:htt
|
||||
|
||||
== Manual Configuration
|
||||
|
||||
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:
|
||||
Instead of using the Spring Boot auto-configuration, you can manually configure the `QdrantVectorStore`. For this you need to add the `spring-ai-qdrant-store` dependency to your project:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ Add the Redis Vector Store and Jedis dependencies
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-redis</artifactId>
|
||||
<artifactId>spring-ai-redis-store</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<!-- Pinecone Vector Store-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-pinecone</artifactId>
|
||||
<artifactId>spring-ai-pinecone-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -149,7 +149,7 @@
|
||||
<!-- Apache Cassandra Vector Store -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-cassandra</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -165,7 +165,7 @@
|
||||
<!-- Redis Vector Store-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-redis</artifactId>
|
||||
<artifactId>spring-ai-redis-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -242,7 +242,7 @@
|
||||
<!-- Qdrant Vector Store-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-azure-vector-store-spring-boot-starter</artifactId>
|
||||
<artifactId>spring-ai-azure-store-spring-boot-starter</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Starter - Azure Vector Store</name>
|
||||
<description>Spring AI Azure Vector Store Auto Configuration</description>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-cassandra-spring-boot-starter</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store-spring-boot-starter</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Starter - Apache Cassandra Vector Store</name>
|
||||
<description>Spring AI Apache Cassandra Vector Store Auto Configuration</description>
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-cassandra</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-pinecone</artifactId>
|
||||
<artifactId>spring-ai-pinecone-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-redis-spring-boot-starter</artifactId>
|
||||
<artifactId>spring-ai-redis-store-spring-boot-starter</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Starter - Redis Vector Store</name>
|
||||
<description>Spring AI Redis Vector Store Auto Configuration</description>
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-redis</artifactId>
|
||||
<artifactId>spring-ai-redis-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -94,7 +94,7 @@
|
||||
<!-- Redis Vector Store-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-redis</artifactId>
|
||||
<artifactId>spring-ai-redis-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -110,7 +110,7 @@
|
||||
<!-- Qdrant Vector Store-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -49,9 +49,7 @@ import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.SearchRequest;
|
||||
import org.springframework.ai.vectorstore.VectorStore;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -65,9 +63,8 @@ import org.springframework.util.StringUtils;
|
||||
* @author Greg Meyer
|
||||
* @author Xiangyang Yu
|
||||
* @author Christian Tzolov
|
||||
* @author Josh Long
|
||||
*/
|
||||
public class AzureVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class AzureVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AzureVectorStore.class);
|
||||
|
||||
@@ -118,53 +115,6 @@ public class AzureVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
*/
|
||||
private final List<MetadataField> filterMetadataFields;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {
|
||||
|
||||
int dimensions = this.embeddingClient.dimensions();
|
||||
|
||||
List<SearchField> fields = new ArrayList<>();
|
||||
|
||||
fields.add(new SearchField(ID_FIELD_NAME, SearchFieldDataType.STRING).setKey(true)
|
||||
.setFilterable(true)
|
||||
.setSortable(true));
|
||||
fields.add(new SearchField(EMBEDDING_FIELD_NAME, SearchFieldDataType.collection(SearchFieldDataType.SINGLE))
|
||||
.setSearchable(true)
|
||||
.setVectorSearchDimensions(dimensions)
|
||||
// This must match a vector search configuration name.
|
||||
.setVectorSearchProfileName(SPRING_AI_VECTOR_PROFILE));
|
||||
fields.add(new SearchField(CONTENT_FIELD_NAME, SearchFieldDataType.STRING).setSearchable(true)
|
||||
.setFilterable(true));
|
||||
fields.add(new SearchField(METADATA_FIELD_NAME, SearchFieldDataType.STRING).setSearchable(true)
|
||||
.setFilterable(true));
|
||||
|
||||
for (MetadataField filterableMetadataField : this.filterMetadataFields) {
|
||||
fields.add(new SearchField(METADATA_FIELD_PREFIX + filterableMetadataField.name(),
|
||||
filterableMetadataField.fieldType())
|
||||
.setSearchable(false)
|
||||
.setFacetable(true));
|
||||
}
|
||||
|
||||
SearchIndex searchIndex = new SearchIndex(this.indexName).setFields(fields)
|
||||
// VectorSearch configuration is required for a vector field. The name used
|
||||
// for the vector search algorithm configuration must match the configuration
|
||||
// used by the search field used for vector search.
|
||||
.setVectorSearch(new VectorSearch()
|
||||
.setProfiles(Collections
|
||||
.singletonList(new VectorSearchProfile(SPRING_AI_VECTOR_PROFILE, SPRING_AI_VECTOR_CONFIG)))
|
||||
.setAlgorithms(Collections.singletonList(new HnswAlgorithmConfiguration(SPRING_AI_VECTOR_CONFIG)
|
||||
.setParameters(new HnswParameters().setM(4)
|
||||
.setEfConstruction(400)
|
||||
.setEfSearch(1000)
|
||||
.setMetric(VectorSearchAlgorithmMetric.COSINE)))));
|
||||
|
||||
SearchIndex index = this.searchIndexClient.createOrUpdateIndex(searchIndex);
|
||||
|
||||
logger.info("Created search index: " + index.getName());
|
||||
|
||||
this.searchClient = this.searchIndexClient.getSearchClient(this.indexName);
|
||||
}
|
||||
|
||||
public record MetadataField(String name, SearchFieldDataType fieldType) {
|
||||
|
||||
public static MetadataField text(String name) {
|
||||
@@ -375,4 +325,51 @@ public class AzureVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
private record AzureSearchDocument(String id, String content, List<Double> embedding, String metadata) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
int dimensions = this.embeddingClient.dimensions();
|
||||
|
||||
List<SearchField> fields = new ArrayList<>();
|
||||
|
||||
fields.add(new SearchField(ID_FIELD_NAME, SearchFieldDataType.STRING).setKey(true)
|
||||
.setFilterable(true)
|
||||
.setSortable(true));
|
||||
fields.add(new SearchField(EMBEDDING_FIELD_NAME, SearchFieldDataType.collection(SearchFieldDataType.SINGLE))
|
||||
.setSearchable(true)
|
||||
.setVectorSearchDimensions(dimensions)
|
||||
// This must match a vector search configuration name.
|
||||
.setVectorSearchProfileName(SPRING_AI_VECTOR_PROFILE));
|
||||
fields.add(new SearchField(CONTENT_FIELD_NAME, SearchFieldDataType.STRING).setSearchable(true)
|
||||
.setFilterable(true));
|
||||
fields.add(new SearchField(METADATA_FIELD_NAME, SearchFieldDataType.STRING).setSearchable(true)
|
||||
.setFilterable(true));
|
||||
|
||||
for (MetadataField filterableMetadataField : this.filterMetadataFields) {
|
||||
fields.add(new SearchField(METADATA_FIELD_PREFIX + filterableMetadataField.name(),
|
||||
filterableMetadataField.fieldType())
|
||||
.setSearchable(false)
|
||||
.setFacetable(true));
|
||||
}
|
||||
|
||||
SearchIndex searchIndex = new SearchIndex(this.indexName).setFields(fields)
|
||||
// VectorSearch configuration is required for a vector field. The name used
|
||||
// for the vector search algorithm configuration must match the configuration
|
||||
// used by the search field used for vector search.
|
||||
.setVectorSearch(new VectorSearch()
|
||||
.setProfiles(Collections
|
||||
.singletonList(new VectorSearchProfile(SPRING_AI_VECTOR_PROFILE, SPRING_AI_VECTOR_CONFIG)))
|
||||
.setAlgorithms(Collections.singletonList(new HnswAlgorithmConfiguration(SPRING_AI_VECTOR_CONFIG)
|
||||
.setParameters(new HnswParameters().setM(4)
|
||||
.setEfConstruction(400)
|
||||
.setEfSearch(1000)
|
||||
.setMetric(VectorSearchAlgorithmMetric.COSINE)))));
|
||||
|
||||
SearchIndex index = this.searchIndexClient.createOrUpdateIndex(searchIndex);
|
||||
|
||||
logger.info("Created search index: " + index.getName());
|
||||
|
||||
this.searchClient = this.searchIndexClient.getSearchClient(this.indexName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-cassandra</artifactId>
|
||||
<artifactId>spring-ai-cassandra-store</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Vector Store – Apache Cassandra</name>
|
||||
<description>Spring AI Vector Store for Apache Cassandra</description>
|
||||
@@ -29,9 +29,7 @@ import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.ai.vectorstore.filter.converter.ChromaFilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -42,10 +40,8 @@ import org.springframework.util.StringUtils;
|
||||
* their similarity to a query, using the {@link ChromaApi} and {@link EmbeddingClient}
|
||||
* for embedding calculations. For more information about how it does this, see the
|
||||
* official <a href="https://www.trychroma.com/">Chroma website</a>.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class ChromaVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class ChromaVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
public static final String DISTANCE_FIELD_NAME = "distance";
|
||||
|
||||
@@ -151,7 +147,7 @@ public class ChromaVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
var collection = this.chromaApi.getCollection(this.collectionName);
|
||||
if (collection == null) {
|
||||
collection = this.chromaApi.createCollection(new ChromaApi.CreateCollectionRequest(this.collectionName));
|
||||
@@ -159,4 +155,4 @@ public class ChromaVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
this.collectionId = collection.id();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,7 @@ import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.Filter;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -50,10 +49,9 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* @author Jemin Huh
|
||||
* @author Wei Jiang
|
||||
* @author Josh Long
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ElasticsearchVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class ElasticsearchVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
// divided by 2 to get score in the range [0, 1]
|
||||
public static final String COSINE_SIMILARITY_FUNCTION = "(cosineSimilarity(params.query_vector, 'embedding') + 1.0) / 2";
|
||||
@@ -221,10 +219,10 @@ public class ElasticsearchVectorStore implements VectorStore, ApplicationListene
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
public void afterPropertiesSet() {
|
||||
if (!indexExists()) {
|
||||
createIndexMapping();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-gemfire</artifactId>
|
||||
<artifactId>spring-ai-gemfire-store</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Vector Store - GemFire</name>
|
||||
<description>Spring AI GemFire Vector Store</description>
|
||||
@@ -55,16 +55,14 @@ import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.ai.vectorstore.filter.converter.MilvusFilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
* @author Josh Long
|
||||
*/
|
||||
public class MilvusVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class MilvusVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MilvusVectorStore.class);
|
||||
|
||||
@@ -98,11 +96,6 @@ public class MilvusVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
|
||||
private final MilvusVectorStoreConfig config;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
this.createCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for the Milvus vector store.
|
||||
*/
|
||||
@@ -385,6 +378,10 @@ public class MilvusVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
// ---------------------------------------------------------------------------------
|
||||
// Initialization
|
||||
// ---------------------------------------------------------------------------------
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.createCollection();
|
||||
}
|
||||
|
||||
void releaseCollection() {
|
||||
if (isDatabaseCollectionExists()) {
|
||||
|
||||
@@ -25,8 +25,7 @@ import com.mongodb.BasicDBObject;
|
||||
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
@@ -37,10 +36,9 @@ import static org.springframework.data.mongodb.core.query.Criteria.where;
|
||||
|
||||
/**
|
||||
* @author Chris Smith
|
||||
* @author Josh Long
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class MongoDBAtlasVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class MongoDBAtlasVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
public static final String ID_FIELD_NAME = "_id";
|
||||
|
||||
@@ -78,6 +76,16 @@ public class MongoDBAtlasVectorStore implements VectorStore, ApplicationListener
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// Create the collection if it does not exist
|
||||
if (!mongoTemplate.collectionExists(this.config.collectionName)) {
|
||||
mongoTemplate.createCollection(this.config.collectionName);
|
||||
}
|
||||
// Create search index, command doesn't do anything if already existing
|
||||
mongoTemplate.executeCommand(createSearchIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the Definition for the search index
|
||||
*/
|
||||
@@ -166,16 +174,6 @@ public class MongoDBAtlasVectorStore implements VectorStore, ApplicationListener
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
// Create the collection if it does not exist
|
||||
if (!mongoTemplate.collectionExists(this.config.collectionName)) {
|
||||
mongoTemplate.createCollection(this.config.collectionName);
|
||||
}
|
||||
// Create search index, command doesn't do anything if already existing
|
||||
mongoTemplate.executeCommand(createSearchIndex());
|
||||
}
|
||||
|
||||
public static class MongoDBVectorStoreConfig {
|
||||
|
||||
private final String collectionName;
|
||||
|
||||
@@ -22,8 +22,7 @@ import org.neo4j.driver.Values;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.Neo4jVectorFilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -35,9 +34,8 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* @author Gerrit Meier
|
||||
* @author Michael Simons
|
||||
* @author Josh Long
|
||||
*/
|
||||
public class Neo4jVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class Neo4jVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
/**
|
||||
* An enum to configure the distance function used in the Neo4j vector index.
|
||||
@@ -72,7 +70,6 @@ public class Neo4jVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
private final String indexName;
|
||||
|
||||
// needed for similarity search call
|
||||
|
||||
private final String indexNameNotSanitized;
|
||||
|
||||
private final String idProperty;
|
||||
@@ -256,29 +253,6 @@ public class Neo4jVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
|
||||
try (var session = this.driver.session(this.config.sessionConfig)) {
|
||||
|
||||
session
|
||||
.run("CREATE CONSTRAINT %s IF NOT EXISTS FOR (n:%s) REQUIRE n.%s IS UNIQUE"
|
||||
.formatted(this.config.constraintName, this.config.label, this.config.idProperty))
|
||||
.consume();
|
||||
|
||||
var statement = """
|
||||
CREATE VECTOR INDEX %s IF NOT EXISTS FOR (n:%s) ON (n.%s)
|
||||
OPTIONS {indexConfig: {
|
||||
`vector.dimensions`: %d,
|
||||
`vector.similarity_function`: '%s'
|
||||
}}
|
||||
""".formatted(this.config.indexName, this.config.label, this.config.embeddingProperty,
|
||||
this.config.embeddingDimension, this.config.distanceType.name);
|
||||
session.run(statement).consume();
|
||||
session.run("CALL db.awaitIndexes()").consume();
|
||||
}
|
||||
}
|
||||
|
||||
public static final int DEFAULT_EMBEDDING_DIMENSION = 1536;
|
||||
|
||||
public static final String DEFAULT_LABEL = "Document";
|
||||
@@ -374,6 +348,29 @@ public class Neo4jVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
try (var session = this.driver.session(this.config.sessionConfig)) {
|
||||
|
||||
session
|
||||
.run("CREATE CONSTRAINT %s IF NOT EXISTS FOR (n:%s) REQUIRE n.%s IS UNIQUE"
|
||||
.formatted(this.config.constraintName, this.config.label, this.config.idProperty))
|
||||
.consume();
|
||||
|
||||
var statement = """
|
||||
CREATE VECTOR INDEX %s IF NOT EXISTS FOR (n:%s) ON (n.%s)
|
||||
OPTIONS {indexConfig: {
|
||||
`vector.dimensions`: %d,
|
||||
`vector.similarity_function`: '%s'
|
||||
}}
|
||||
""".formatted(this.config.indexName, this.config.label, this.config.embeddingProperty,
|
||||
this.config.embeddingDimension, this.config.distanceType.name);
|
||||
session.run(statement).consume();
|
||||
session.run("CALL db.awaitIndexes()").consume();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> documentToRecord(Document document) {
|
||||
var embedding = this.embeddingClient.embed(document);
|
||||
document.setEmbedding(embedding);
|
||||
@@ -416,4 +413,4 @@ public class Neo4jVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
Map.copyOf(metaData));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -35,8 +35,7 @@ import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.ai.vectorstore.filter.converter.PgVectorFilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -50,9 +49,8 @@ import org.springframework.util.StringUtils;
|
||||
* vector index will be auto-created if not available.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @author Josh Long
|
||||
*/
|
||||
public class PgVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class PgVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PgVectorStore.class);
|
||||
|
||||
@@ -80,40 +78,6 @@ public class PgVectorStore implements VectorStore, ApplicationListener<Applicati
|
||||
|
||||
private PgIndexType createIndexMethod;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
try {
|
||||
// Enable the PGVector, JSONB and UUID support.
|
||||
this.jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS vector");
|
||||
this.jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS hstore");
|
||||
this.jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"");
|
||||
|
||||
// Remove existing VectorStoreTable
|
||||
if (this.removeExistingVectorStoreTable) {
|
||||
this.jdbcTemplate.execute("DROP TABLE IF EXISTS " + VECTOR_TABLE_NAME);
|
||||
}
|
||||
|
||||
this.jdbcTemplate.execute(String.format("""
|
||||
CREATE TABLE IF NOT EXISTS %s (
|
||||
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
content text,
|
||||
metadata json,
|
||||
embedding vector(%d)
|
||||
)
|
||||
""", VECTOR_TABLE_NAME, this.embeddingDimensions()));
|
||||
|
||||
if (this.createIndexMethod != PgIndexType.NONE) {
|
||||
this.jdbcTemplate.execute(String.format("""
|
||||
CREATE INDEX IF NOT EXISTS %s ON %s USING %s (embedding %s)
|
||||
""", VECTOR_INDEX_NAME, VECTOR_TABLE_NAME, this.createIndexMethod,
|
||||
this.getDistanceType().index));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, pgvector performs exact nearest neighbor search, which provides perfect
|
||||
* recall. You can add an index to use approximate nearest neighbor search, which
|
||||
@@ -367,6 +331,33 @@ public class PgVectorStore implements VectorStore, ApplicationListener<Applicati
|
||||
// ---------------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ---------------------------------------------------------------------------------
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// Enable the PGVector, JSONB and UUID support.
|
||||
this.jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS vector");
|
||||
this.jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS hstore");
|
||||
this.jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"");
|
||||
|
||||
// Remove existing VectorStoreTable
|
||||
if (this.removeExistingVectorStoreTable) {
|
||||
this.jdbcTemplate.execute("DROP TABLE IF EXISTS " + VECTOR_TABLE_NAME);
|
||||
}
|
||||
|
||||
this.jdbcTemplate.execute(String.format("""
|
||||
CREATE TABLE IF NOT EXISTS %s (
|
||||
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
content text,
|
||||
metadata json,
|
||||
embedding vector(%d)
|
||||
)
|
||||
""", VECTOR_TABLE_NAME, this.embeddingDimensions()));
|
||||
|
||||
if (this.createIndexMethod != PgIndexType.NONE) {
|
||||
this.jdbcTemplate.execute(String.format("""
|
||||
CREATE INDEX IF NOT EXISTS %s ON %s USING %s (embedding %s)
|
||||
""", VECTOR_INDEX_NAME, VECTOR_TABLE_NAME, this.createIndexMethod, this.getDistanceType().index));
|
||||
}
|
||||
}
|
||||
|
||||
int embeddingDimensions() {
|
||||
// The manually set dimensions have precedence over the computed one.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-pinecone</artifactId>
|
||||
<artifactId>spring-ai-pinecone-store</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Vector Store - Pinecone </name>
|
||||
<url>https://github.com/spring-projects/spring-ai</url>
|
||||
@@ -8,7 +8,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-qdrant</artifactId>
|
||||
<artifactId>spring-ai-qdrant-store</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Vector Store - QDrant</name>
|
||||
|
||||
@@ -15,12 +15,24 @@
|
||||
*/
|
||||
package org.springframework.ai.vectorstore.qdrant;
|
||||
|
||||
import static io.qdrant.client.PointIdFactory.id;
|
||||
import static io.qdrant.client.ValueFactory.value;
|
||||
import static io.qdrant.client.VectorsFactory.vectors;
|
||||
import static io.qdrant.client.WithPayloadSelectorFactory.enable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.SearchRequest;
|
||||
import org.springframework.ai.vectorstore.VectorStore;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
@@ -32,19 +44,6 @@ import io.qdrant.client.grpc.Points.ScoredPoint;
|
||||
import io.qdrant.client.grpc.Points.SearchPoints;
|
||||
import io.qdrant.client.grpc.Points.UpdateStatus;
|
||||
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.SearchRequest;
|
||||
import org.springframework.ai.vectorstore.VectorStore;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static io.qdrant.client.PointIdFactory.id;
|
||||
import static io.qdrant.client.ValueFactory.value;
|
||||
import static io.qdrant.client.VectorsFactory.vectors;
|
||||
import static io.qdrant.client.WithPayloadSelectorFactory.enable;
|
||||
|
||||
/**
|
||||
* Qdrant vectorStore implementation. This store supports creating, updating, deleting,
|
||||
* and similarity searching of documents in a Qdrant collection.
|
||||
@@ -52,10 +51,9 @@ import static io.qdrant.client.WithPayloadSelectorFactory.enable;
|
||||
* @author Anush Shetty
|
||||
* @author Christian Tzolov
|
||||
* @author Eddú Meléndez
|
||||
* @author Josh Long
|
||||
* @since 0.8.1
|
||||
*/
|
||||
public class QdrantVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
public class QdrantVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
private static final String CONTENT_FIELD_NAME = "doc_content";
|
||||
|
||||
@@ -86,7 +84,6 @@ public class QdrantVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
*
|
||||
* @param builder The configuration builder.
|
||||
*/
|
||||
|
||||
private QdrantVectorStoreConfig(Builder builder) {
|
||||
this.collectionName = builder.collectionName;
|
||||
}
|
||||
@@ -161,24 +158,6 @@ public class QdrantVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
this.qdrantClient = qdrantClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
|
||||
// Create the collection if it does not exist.
|
||||
if (!isCollectionExists()) {
|
||||
var vectorParams = VectorParams.newBuilder()
|
||||
.setDistance(Distance.Cosine)
|
||||
.setSize(this.embeddingClient.dimensions())
|
||||
.build();
|
||||
try {
|
||||
this.qdrantClient.createCollectionAsync(this.collectionName, vectorParams).get();
|
||||
} //
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a list of documents to the vector store.
|
||||
* @param documents The list of documents to be added.
|
||||
@@ -261,6 +240,7 @@ public class QdrantVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
|
||||
/**
|
||||
* Extracts metadata from a Protobuf Struct.
|
||||
* @param metadataStruct The Protobuf Struct containing metadata.
|
||||
* @return The metadata as a map.
|
||||
*/
|
||||
private Document toDocument(ScoredPoint point) {
|
||||
@@ -304,6 +284,18 @@ public class QdrantVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
return doubleList.stream().map(d -> d.floatValue()).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// Create the collection if it does not exist.
|
||||
if (!isCollectionExists()) {
|
||||
var vectorParams = VectorParams.newBuilder()
|
||||
.setDistance(Distance.Cosine)
|
||||
.setSize(this.embeddingClient.dimensions())
|
||||
.build();
|
||||
this.qdrantClient.createCollectionAsync(this.collectionName, vectorParams).get();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCollectionExists() {
|
||||
try {
|
||||
return this.qdrantClient.listCollectionsAsync().get().stream().anyMatch(c -> c.equals(this.collectionName));
|
||||
@@ -313,4 +305,4 @@ public class QdrantVectorStore implements VectorStore, ApplicationListener<Appli
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-ai-redis</artifactId>
|
||||
<artifactId>spring-ai-redis-store</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring AI Vector Store - Redis </name>
|
||||
<description>Spring AI Vector Store - Redis </description>
|
||||
@@ -28,6 +28,13 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import redis.clients.jedis.JedisPooled;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
import redis.clients.jedis.json.Path2;
|
||||
@@ -44,14 +51,6 @@ import redis.clients.jedis.search.schemafields.TextField;
|
||||
import redis.clients.jedis.search.schemafields.VectorField;
|
||||
import redis.clients.jedis.search.schemafields.VectorField.VectorAlgorithm;
|
||||
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* The RedisVectorStore is for managing and querying vector data in a Redis database. It
|
||||
* offers functionalities like adding, deleting, and performing similarity searches on
|
||||
@@ -69,27 +68,11 @@ import org.springframework.util.CollectionUtils;
|
||||
*
|
||||
* @author Julien Ruaux
|
||||
* @author Christian Tzolov
|
||||
* @author Josh Long
|
||||
* @see VectorStore
|
||||
* @see RedisVectorStoreConfig
|
||||
* @see EmbeddingClient
|
||||
*/
|
||||
public class RedisVectorStore implements VectorStore, ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
// If index already exists don't do anything
|
||||
if (this.jedis.ftList().contains(this.config.indexName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String response = this.jedis.ftCreate(this.config.indexName,
|
||||
FTCreateParams.createParams().on(IndexDataType.JSON).addPrefix(this.config.prefix), schemaFields());
|
||||
if (!RESPONSE_OK.test(response)) {
|
||||
String message = MessageFormat.format("Could not create index: {0}", response);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
public class RedisVectorStore implements VectorStore, InitializingBean {
|
||||
|
||||
public enum Algorithm {
|
||||
|
||||
@@ -419,6 +402,22 @@ public class RedisVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
return "(" + this.filterExpressionConverter.convertExpression(request.getFilterExpression()) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
// If index already exists don't do anything
|
||||
if (this.jedis.ftList().contains(this.config.indexName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String response = this.jedis.ftCreate(this.config.indexName,
|
||||
FTCreateParams.createParams().on(IndexDataType.JSON).addPrefix(this.config.prefix), schemaFields());
|
||||
if (!RESPONSE_OK.test(response)) {
|
||||
String message = MessageFormat.format("Could not create index: {0}", response);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private Iterable<SchemaField> schemaFields() {
|
||||
Map<String, Object> vectorAttrs = new HashMap<>();
|
||||
vectorAttrs.put("DIM", this.embeddingClient.dimensions());
|
||||
@@ -476,4 +475,4 @@ public class RedisVectorStore implements VectorStore, ApplicationListener<Applic
|
||||
return embeddingFloat;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -551,4 +551,4 @@ public class WeaviateVectorStore implements VectorStore, InitializingBean {
|
||||
this.delete(List.of(document.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user