Add getNativeClient API to VectorStore interface

Adds getNativeClient API to VectorStore interface allowing access to the underlying native client implementation.

This change:
- Adds getNativeClient() default method to VectorStore interface returning Optional<T>
- Implements getNativeClient() in all vector store implementations exposing their respective native clients
- Adds integration tests verifying native client access for all implementations

Fixes: #2137

Signed-off-by: Soby Chacko <soby.chacko@broadcom.com>
This commit is contained in:
Soby Chacko
2025-02-02 15:20:33 -05:00
committed by Mark Pollack
parent 54463e6622
commit 16a596f8b7
53 changed files with 618 additions and 2 deletions

View File

@@ -44,6 +44,10 @@ public interface VectorStore extends DocumentWriter {
List<Document> similaritySearch(String query);
List<Document> similaritySearch(SearchRequest request);
default <T> Optional<T> getNativeClient() {
return Optional.empty();
}
}
```

View File

@@ -319,3 +319,20 @@ nodetool import wikidata articles ${CASSANDRA_DATA}/data/wikidata/articles-*/
* An alternative to `nodetool import` is to just restart Cassandra.
* If there are any failures in the indexes they will be rebuilt automatically.
====
== Accessing the Native Client
The Cassandra Vector Store implementation provides access to the underlying native Cassandra client (`CqlSession`) through the `getNativeClient()` method:
[source,java]
----
CassandraVectorStore vectorStore = context.getBean(CassandraVectorStore.class);
Optional<CqlSession> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
CqlSession session = nativeClient.get();
// Use the native client for Cassandra-specific operations
}
----
The native client gives you access to Cassandra-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -205,3 +205,20 @@ Add the following dependency in your Maven project:
<artifactId>spring-ai-azure-cosmos-db-store</artifactId>
</dependency>
----
== Accessing the Native Client
The Azure Cosmos DB Vector Store implementation provides access to the underlying native Azure Cosmos DB client (`CosmosClient`) through the `getNativeClient()` method:
[source,java]
----
CosmosDBVectorStore vectorStore = context.getBean(CosmosDBVectorStore.class);
Optional<CosmosClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
CosmosClient client = nativeClient.get();
// Use the native client for Azure Cosmos DB-specific operations
}
----
The native client gives you access to Azure Cosmos DB-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -226,3 +226,20 @@ is converted into the following Azure OData link:https://learn.microsoft.com/en-
----
$filter search.in(meta_country, 'UK,NL', ',') and meta_year ge 2020
----
== Accessing the Native Client
The Azure Vector Store implementation provides access to the underlying native Azure Search client (`SearchClient`) through the `getNativeClient()` method:
[source,java]
----
AzureVectorStore vectorStore = context.getBean(AzureVectorStore.class);
Optional<SearchClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
SearchClient client = nativeClient.get();
// Use the native client for Azure Search-specific operations
}
----
The native client gives you access to Azure Search-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -0,0 +1,17 @@
== Accessing the Native Client
The Coherence Vector Store implementation provides access to the underlying native Coherence client (`Session`) through the `getNativeClient()` method:
[source,java]
----
CoherenceVectorStore vectorStore = context.getBean(CoherenceVectorStore.class);
Optional<Session> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
Session session = nativeClient.get();
// Use the native client for Coherence-specific operations
}
----
The native client gives you access to Coherence-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -269,3 +269,20 @@ public EmbeddingModel embeddingModel() {
return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv("OPENAI_API_KEY")));
}
----
== Accessing the Native Client
The Elasticsearch Vector Store implementation provides access to the underlying native Elasticsearch client (`ElasticsearchClient`) through the `getNativeClient()` method:
[source,java]
----
ElasticsearchVectorStore vectorStore = context.getBean(ElasticsearchVectorStore.class);
Optional<ElasticsearchClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
ElasticsearchClient client = nativeClient.get();
// Use the native client for Elasticsearch-specific operations
}
----
The native client gives you access to Elasticsearch-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -204,3 +204,20 @@ vectorStore.similaritySearch(SearchRequest.builder()
----
NOTE: These filter expressions are automatically converted into the equivalent MariaDB JSON path expressions.
== Accessing the Native Client
The MariaDB Vector Store implementation provides access to the underlying native JDBC client (`JdbcTemplate`) through the `getNativeClient()` method:
[source,java]
----
MariaDBVectorStore vectorStore = context.getBean(MariaDBVectorStore.class);
Optional<JdbcTemplate> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
JdbcTemplate jdbc = nativeClient.get();
// Use the native client for MariaDB-specific operations
}
----
The native client gives you access to MariaDB-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -229,3 +229,20 @@ If Docker complains about resources, then execute:
----
docker system prune --all --force --volumes
----
== Accessing the Native Client
The Milvus Vector Store implementation provides access to the underlying native Milvus client (`MilvusServiceClient`) through the `getNativeClient()` method:
[source,java]
----
MilvusVectorStore vectorStore = context.getBean(MilvusVectorStore.class);
Optional<MilvusServiceClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
MilvusServiceClient client = nativeClient.get();
// Use the native client for Milvus-specific operations
}
----
The native client gives you access to Milvus-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -228,3 +228,20 @@ To get started with Spring AI and MongoDB:
* See the https://www.mongodb.com/docs/atlas/atlas-vector-search/ai-integrations/spring-ai/#std-label-spring-ai[Getting Started guide for Spring AI Integration].
* For a comprehensive code example demonstrating Retrieval Augmented Generation (RAG) with Spring AI and MongoDB, refer to this https://www.mongodb.com/developer/languages/java/retrieval-augmented-generation-spring-ai/[detailed tutorial].
== Accessing the Native Client
The MongoDB Atlas Vector Store implementation provides access to the underlying native MongoDB client (`MongoClient`) through the `getNativeClient()` method:
[source,java]
----
MongoDBAtlasVectorStore vectorStore = context.getBean(MongoDBAtlasVectorStore.class);
Optional<MongoClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
MongoClient client = nativeClient.get();
// Use the native client for MongoDB-specific operations
}
----
The native client gives you access to MongoDB-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -237,3 +237,20 @@ is converted into the proprietary Neo4j filter format:
----
node.`metadata.author` IN ["john","jill"] AND node.`metadata.'article_type'` = "blog"
----
== Accessing the Native Client
The Neo4j Vector Store implementation provides access to the underlying native Neo4j client (`Driver`) through the `getNativeClient()` method:
[source,java]
----
Neo4jVectorStore vectorStore = context.getBean(Neo4jVectorStore.class);
Optional<Driver> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
Driver driver = nativeClient.get();
// Use the native client for Neo4j-specific operations
}
----
The native client gives you access to Neo4j-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -238,3 +238,20 @@ is converted into the proprietary OpenSearch filter format:
----
(metadata.author:john OR jill) AND metadata.article_type:blog
----
== Accessing the Native Client
The OpenSearch Vector Store implementation provides access to the underlying native OpenSearch client (`OpenSearchClient`) through the `getNativeClient()` method:
[source,java]
----
OpenSearchVectorStore vectorStore = context.getBean(OpenSearchVectorStore.class);
Optional<OpenSearchClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
OpenSearchClient client = nativeClient.get();
// Use the native client for OpenSearch-specific operations
}
----
The native client gives you access to OpenSearch-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -206,3 +206,20 @@ You can then connect to the database using:
----
sql mlops/mlops@localhost/freepdb1
----
== Accessing the Native Client
The Oracle Vector Store implementation provides access to the underlying native Oracle client (`OracleConnection`) through the `getNativeClient()` method:
[source,java]
----
OracleVectorStore vectorStore = context.getBean(OracleVectorStore.class);
Optional<OracleConnection> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
OracleConnection connection = nativeClient.get();
// Use the native client for Oracle-specific operations
}
----
The native client gives you access to Oracle-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -243,3 +243,20 @@ You can connect to this server like this:
----
psql -U postgres -h localhost -p 5432
----
== Accessing the Native Client
The PGVector Store implementation provides access to the underlying native JDBC client (`JdbcTemplate`) through the `getNativeClient()` method:
[source,java]
----
PgVectorStore vectorStore = context.getBean(PgVectorStore.class);
Optional<JdbcTemplate> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
JdbcTemplate jdbc = nativeClient.get();
// Use the native client for PostgreSQL-specific operations
}
----
The native client gives you access to PostgreSQL-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -222,3 +222,20 @@ List<Document> results = vectorStore.similaritySearch(SearchRequest.query("Sprin
----
If all goes well, you should retrieve the document containing the text "Spring AI rocks!!".
== Accessing the Native Client
The Pinecone Vector Store implementation provides access to the underlying native Pinecone client (`PineconeConnection`) through the `getNativeClient()` method:
[source,java]
----
PineconeVectorStore vectorStore = context.getBean(PineconeVectorStore.class);
Optional<PineconeConnection> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
PineconeConnection client = nativeClient.get();
// Use the native client for Pinecone-specific operations
}
----
The native client gives you access to Pinecone-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -194,3 +194,20 @@ vectorStore.similaritySearch(SearchRequest.builder()
----
NOTE: These (portable) filter expressions get automatically converted into the proprietary Qdrant link:https://qdrant.tech/documentation/concepts/filtering/[filter expressions].
== Accessing the Native Client
The Qdrant Vector Store implementation provides access to the underlying native Qdrant client (`QdrantClient`) through the `getNativeClient()` method:
[source,java]
----
QdrantVectorStore vectorStore = context.getBean(QdrantVectorStore.class);
Optional<QdrantClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
QdrantClient client = nativeClient.get();
// Use the native client for Qdrant-specific operations
}
----
The native client gives you access to Qdrant-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -212,3 +212,20 @@ public EmbeddingModel embeddingModel() {
You must list explicitly all metadata field names and types (`TAG`, `TEXT`, or `NUMERIC`) for any metadata field used in filter expressions.
The `metadataFields` above registers filterable metadata fields: `country` of type `TAG`, `year` of type `NUMERIC`.
====
== Accessing the Native Client
The Redis Vector Store implementation provides access to the underlying native Redis client (`JedisPooled`) through the `getNativeClient()` method:
[source,java]
----
RedisVectorStore vectorStore = context.getBean(RedisVectorStore.class);
Optional<JedisPooled> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
JedisPooled jedis = nativeClient.get();
// Use the native client for Redis-specific operations
}
----
The native client gives you access to Redis-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -229,3 +229,20 @@ If you are not retrieving the documents in the expected order or the search resu
Embedding models can have a significant impact on the search results (i.e. make sure if your data is in Spanish to use a Spanish or multilingual embedding model).
====
== Accessing the Native Client
The Typesense Vector Store implementation provides access to the underlying native Typesense client (`Client`) through the `getNativeClient()` method:
[source,java]
----
TypesenseVectorStore vectorStore = context.getBean(TypesenseVectorStore.class);
Optional<Client> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
Client client = nativeClient.get();
// Use the native client for Typesense-specific operations
}
----
The native client gives you access to Typesense-specific features and operations that might not be exposed through the `VectorStore` interface.

View File

@@ -230,3 +230,20 @@ You can use the following properties in your Spring Boot configuration to custom
|`spring.ai.vectorstore.weaviate.consistency-level`|Desired tradeoff between consistency and speed|ConsistentLevel.ONE
|`spring.ai.vectorstore.weaviate.filter-field`|Configures metadata fields that can be used in filters. Format: spring.ai.vectorstore.weaviate.filter-field.<field-name>=<field-type>|
|===
== Accessing the Native Client
The Weaviate Vector Store implementation provides access to the underlying native Weaviate client (`WeaviateClient`) through the `getNativeClient()` method:
[source,java]
----
WeaviateVectorStore vectorStore = context.getBean(WeaviateVectorStore.class);
Optional<WeaviateClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
WeaviateClient client = nativeClient.get();
// Use the native client for Weaviate-specific operations
}
----
The native client gives you access to Weaviate-specific features and operations that might not be exposed through the `VectorStore` interface.