From a55d09aa7a513d7ffee046a5dc983266a0e8a0c4 Mon Sep 17 00:00:00 2001 From: Ilayaperumal Gopinathan Date: Fri, 20 Dec 2024 21:44:01 +0000 Subject: [PATCH] Update document for SearchRequest builder changes --- .../modules/ROOT/pages/api/advisors.adoc | 6 +- .../modules/ROOT/pages/api/chatclient.adoc | 8 ++- .../api/retrieval-augmented-generation.adoc | 19 ++++- .../modules/ROOT/pages/api/testing.adoc | 2 +- .../modules/ROOT/pages/api/vectordbs.adoc | 69 ++++++++++++++++--- .../pages/api/vectordbs/apache-cassandra.adoc | 14 ++-- .../pages/api/vectordbs/azure-cosmos-db.adoc | 8 +-- .../ROOT/pages/api/vectordbs/azure.adoc | 12 ++-- .../ROOT/pages/api/vectordbs/chroma.adoc | 14 ++-- .../pages/api/vectordbs/elasticsearch.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/gemfire.adoc | 6 +- .../ROOT/pages/api/vectordbs/mariadb.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/milvus.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/mongodb.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/neo4j.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/opensearch.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/oracle.adoc | 12 ++-- .../ROOT/pages/api/vectordbs/pgvector.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/pinecone.adoc | 16 ++--- .../ROOT/pages/api/vectordbs/qdrant.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/redis.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/typesense.adoc | 14 ++-- .../ROOT/pages/api/vectordbs/weaviate.adoc | 12 ++-- 23 files changed, 202 insertions(+), 136 deletions(-) diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/advisors.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/advisors.adoc index 204bb2f2b..56e61a7ee 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/advisors.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/advisors.adoc @@ -5,7 +5,7 @@ The Spring AI Advisors API provides a flexible and powerful way to intercept, modify, and enhance AI-driven interactions in your Spring applications. By leveraging the Advisors API, developers can create more sophisticated, reusable, and maintainable AI components. -The key benefits include encapsulating recurring Generative AI patterns, transforming data sent to and from Language Models (LLMs), and providing portability across various models and use cases. +The key benefits include encapsulating recurring Generative AI patterns, transforming data sent to and from Large Language Models (LLMs), and providing portability across various models and use cases. You can configure existing advisors using the xref:api/chatclient.adoc#_advisor_configuration_in_chatclient[ChatClient API] as shown in the following example: @@ -14,7 +14,7 @@ You can configure existing advisors using the xref:api/chatclient.adoc#_advisor_ var chatClient = ChatClient.builder(chatModel) .defaultAdvisors( new MessageChatMemoryAdvisor(chatMemory), // chat-memory advisor - new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()) // RAG advisor + new QuestionAnswerAdvisor(vectorStore) // RAG advisor ) .build(); @@ -31,6 +31,8 @@ It is recommend to register the advisors at build time using builder's `defaultA Advisors also participate in the Observability stack, so you can view metrics and traces related to their execution. +xref:ROOT:api/retrieval-augmented-generation.adoc#_questionansweradvisor[Learn about Question Answer Advisor] + == Core Components The API consists of `CallAroundAdvisor` and `CallAroundAdvisorChain` for non-streaming scenarios, and `StreamAroundAdvisor` and `StreamAroundAdvisorChain` for streaming scenarios. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc index fab86cece..94ef91768 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc @@ -355,7 +355,7 @@ ChatClient.builder(chatModel) .prompt() .advisors( new MessageChatMemoryAdvisor(chatMemory), - new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()) + new QuestionAnswerAdvisor(vectorStore) ) .user(userText) .call() @@ -364,6 +364,8 @@ ChatClient.builder(chatModel) In this configuration, the `MessageChatMemoryAdvisor` will be executed first, adding the conversation history to the prompt. Then, the `QuestionAnswerAdvisor` will perform its search based on the user's question and the added conversation history, potentially providing more relevant results. +xref:ROOT:api/retrieval-augmented-generation.adoc#_questionansweradvisor[Learn about Question Answer Advisor] + === Retrieval Augmented Generation Refer to the xref:_retrieval_augmented_generation[Retrieval Augmented Generation] guide. @@ -424,7 +426,7 @@ public class CustomerSupportAssistant { """) .defaultAdvisors( new MessageChatMemoryAdvisor(chatMemory), // CHAT MEMORY - new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()), // RAG + new QuestionAnswerAdvisor(vectorStore), // RAG new SimpleLoggerAdvisor()) .defaultFunctions("getBookingDetails", "changeBooking", "cancelBooking") // FUNCTION CALLING .build(); @@ -443,7 +445,7 @@ public class CustomerSupportAssistant { } ---- - +xref:ROOT:api/retrieval-augmented-generation.adoc#_questionansweradvisor[Learn about Question Answer Advisor] === Logging diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/retrieval-augmented-generation.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/retrieval-augmented-generation.adoc index b9edd059e..55630a0bf 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/retrieval-augmented-generation.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/retrieval-augmented-generation.adoc @@ -26,15 +26,28 @@ Assuming you have already loaded data into a `VectorStore`, you can perform Retr ---- ChatResponse response = ChatClient.builder(chatModel) .build().prompt() - .advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())) + .advisors(new QuestionAnswerAdvisor(vectorStore) .user(userText) .call() .chatResponse(); ---- -In this example, the `SearchRequest.defaults()` will perform a similarity search over all documents in the Vector Database. +In this example, the `QuestionAnswerAdvisor` will perform a similarity search over all documents in the Vector Database. To restrict the types of documents that are searched, the `SearchRequest` takes an SQL like filter expression that is portable across all `VectorStores`. +This filter expression can be configured when creating the `QuestionAnswerAdvisor` and hence will always apply to all `ChatClient` requests or it can be provided at runtime per request. + +Here is how to create an instance of `QuestionAnswerAdvisor` where the threshold is `0.8` and to return the top `6` reulsts. + + +[source,java] +---- +var qaAdvisor = new QuestionAnswerAdvisor(this.vectorStore, + SearchRequest.builder().similarityThreshold(0.8d).topK(6).build()); +---- + + + ==== Dynamic Filter Expressions Update the `SearchRequest` filter expression at runtime using the `FILTER_EXPRESSION` advisor context parameter: @@ -42,7 +55,7 @@ Update the `SearchRequest` filter expression at runtime using the `FILTER_EXPRES [source,java] ---- ChatClient chatClient = ChatClient.builder(chatModel) - .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())) + .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.builder().build())) .build(); // Update filter expression at runtime diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testing.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testing.adoc index f47e6d95c..79ad8ca13 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testing.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testing.adoc @@ -75,7 +75,7 @@ void testEvaluation() { ChatResponse response = ChatClient.builder(chatModel) .build().prompt() - .advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())) + .advisors(new QuestionAnswerAdvisor(vectorStore)) .user(userText) .call() .chatResponse(); diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs.adoc index 2e39cc273..396b29de9 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs.adoc @@ -44,20 +44,69 @@ and the related `SearchRequest` builder: ```java public class SearchRequest { - public final String query; - private int topK = 4; - private double similarityThreshold = SIMILARITY_THRESHOLD_ALL; + public static final double SIMILARITY_THRESHOLD_ACCEPT_ALL = 0.0; + + public static final int DEFAULT_TOP_K = 4; + + private String query = ""; + + private int topK = DEFAULT_TOP_K; + + private double similarityThreshold = SIMILARITY_THRESHOLD_ACCEPT_ALL; + + @Nullable private Filter.Expression filterExpression; - public static SearchRequest query(String query) { return new SearchRequest(query); } + public static Builder from(SearchRequest originalSearchRequest) { + return builder().query(originalSearchRequest.getQuery()) + .topK(originalSearchRequest.getTopK()) + .similarityThreshold(originalSearchRequest.getSimilarityThreshold()) + .filterExpression(originalSearchRequest.getFilterExpression()); + } - private SearchRequest(String query) { this.query = query; } + public static class Builder { - public SearchRequest topK(int topK) {...} - public SearchRequest similarityThreshold(double threshold) {...} - public SearchRequest similarityThresholdAll() {...} - public SearchRequest filterExpression(Filter.Expression expression) {...} - public SearchRequest filterExpression(String textExpression) {...} + private final SearchRequest searchRequest = new SearchRequest(); + + public Builder query(String query) { + Assert.notNull(query, "Query can not be null."); + this.searchRequest.query = query; + return this; + } + + public Builder topK(int topK) { + Assert.isTrue(topK >= 0, "TopK should be positive."); + this.searchRequest.topK = topK; + return this; + } + + public Builder similarityThreshold(double threshold) { + Assert.isTrue(threshold >= 0 && threshold <= 1, "Similarity threshold must be in [0,1] range."); + this.searchRequest.similarityThreshold = threshold; + return this; + } + + public Builder similarityThresholdAll() { + this.searchRequest.similarityThreshold = 0.0; + return this; + } + + public Builder filterExpression(@Nullable Filter.Expression expression) { + this.searchRequest.filterExpression = expression; + return this; + } + + public Builder filterExpression(@Nullable String textExpression) { + this.searchRequest.filterExpression = (textExpression != null) + ? new FilterExpressionTextParser().parse(textExpression) : null; + return this; + } + + public SearchRequest build() { + return this.searchRequest; + } + + } public String getQuery() {...} public int getTopK() {...} diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/apache-cassandra.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/apache-cassandra.adoc index 88a20338d..1e0885e0f 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/apache-cassandra.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/apache-cassandra.adoc @@ -142,7 +142,7 @@ And retrieve documents similar to a query: [source,java] ---- List results = vectorStore.similaritySearch( - SearchRequest.query("Spring").topK(5)); + SearchRequest.builder().query("Spring").topK(5).build()); ---- You can also limit results based on a similarity threshold: @@ -150,9 +150,9 @@ You can also limit results based on a similarity threshold: [source,java] ---- List results = vectorStore.similaritySearch( - SearchRequest.query("Spring") + SearchRequest.builder().query("Spring") .topK(5) - .similarityThreshold(0.5d)); + .similarityThreshold(0.5d).build()); ---- === Advanced Configuration @@ -192,9 +192,9 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.query("The World") + SearchRequest.builder().query("The World") .topK(5) - .filterExpression("country in ['UK', 'NL'] && year >= 2020")); + .filterExpression("country in ['UK', 'NL'] && year >= 2020").build()); ---- or programmatically using the expression DSL: @@ -208,9 +208,9 @@ Filter.Expression f = new FilterExpressionBuilder() ).build(); vectorStore.similaritySearch( - SearchRequest.query("The World") + SearchRequest.builder().query("The World") .topK(5) - .filterExpression(f)); + .filterExpression(f).build()); ---- The portable filter expressions get automatically converted into link:https://cassandra.apache.org/doc/latest/cassandra/developing/cql/index.html[CQL queries]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure-cosmos-db.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure-cosmos-db.adoc index 6e1a3c03c..cc1bb3130 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure-cosmos-db.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure-cosmos-db.adoc @@ -69,7 +69,7 @@ public class DemoApplication implements CommandLineRunner { Document document1 = new Document(UUID.randomUUID().toString(), "Sample content1", Map.of("key1", "value1")); Document document2 = new Document(UUID.randomUUID().toString(), "Sample content2", Map.of("key2", "value2")); this.vectorStore.add(List.of(document1, document2)); - List results = this.vectorStore.similaritySearch(SearchRequest.query("Sample content").topK(1)); + List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Sample content").topK(1).build()); log.info("Search results: {}", results); @@ -139,9 +139,9 @@ Document document2 = new Document("2", "A document about the Netherlands", this. vectorStore.add(List.of(document1, document2)); FilterExpressionBuilder builder = new FilterExpressionBuilder(); -List results = vectorStore.similaritySearch(SearchRequest.query("The World") +List results = vectorStore.similaritySearch(SearchRequest.builder().query("The World") .topK(10) - .filterExpression((this.builder.in("country", "UK", "NL")).build())); + .filterExpression((this.builder.in("country", "UK", "NL")).build()).build()); ---- == Setting up Azure Cosmos DB Vector Store without Auto Configuration @@ -192,7 +192,7 @@ public class DemoApplication implements CommandLineRunner { Document document2 = new Document(UUID.randomUUID().toString(), "Sample content2", Map.of("key2", "value2")); this.vectorStore.add(List.of(document1, document2)); - List results = this.vectorStore.similaritySearch(SearchRequest.query("Sample content").topK(1)); + List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Sample content").topK(1).build()); log.info("Search results: {}", results); } diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure.adoc index 07981981e..bc508da47 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/azure.adoc @@ -169,9 +169,9 @@ And finally, retrieve documents similar to a query: [source,java] ---- List results = vectorStore.similaritySearch( - SearchRequest + SearchRequest.builder() .query("Spring") - .topK(5)); + .topK(5).build()); ---- If all goes well, you should retrieve the document containing the text "Spring AI rocks!!". @@ -185,11 +185,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest + SearchRequest.builder() .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("country in ['UK', 'NL'] && year >= 2020")); + .filterExpression("country in ['UK', 'NL'] && year >= 2020").build()); ---- or programmatically using the expression DSL: @@ -199,13 +199,13 @@ or programmatically using the expression DSL: FilterExpressionBuilder b = new FilterExpressionBuilder(); vectorStore.similaritySearch( - SearchRequest + SearchRequest.builder() .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("country", "UK", "NL"), - b.gte("year", 2020)).build())); + b.gte("year", 2020)).build()).build()); ---- The portable filter expressions get automatically converted into the proprietary Azure Search link:https://learn.microsoft.com/en-us/azure/search/search-query-odata-filter[OData filters]. For example, the following portable filter expression: diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc index 32bbab169..d208feb88 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc @@ -101,7 +101,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- === Configuration properties @@ -137,11 +137,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -150,13 +150,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into the proprietary Chroma `where` link:https://docs.trychroma.com/usage-guide#using-where-filters[filter expressions]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/elasticsearch.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/elasticsearch.adoc index 58ce382b0..5b18a7ec0 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/elasticsearch.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/elasticsearch.adoc @@ -98,7 +98,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[elasticsearchvector-properties]] @@ -171,11 +171,11 @@ For example, you can use either the text expression language: [source,java] ---- -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'")); + .filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -184,13 +184,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author", "john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into the proprietary Elasticsearch link:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html[Query string query]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/gemfire.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/gemfire.adoc index 08b1b9742..0424951a6 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/gemfire.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/gemfire.adoc @@ -122,7 +122,7 @@ vectorStore.add(documents); [source,java] ---- List results = vectorStore.similaritySearch( - SearchRequest.query("Spring").topK(5)); + SearchRequest.builder().query("Spring").topK(5).build()); ---- You should retrieve the document containing the text "Spring AI rocks!!". @@ -131,7 +131,7 @@ You can also limit the number of results using a similarity threshold: [source,java] ---- List results = vectorStore.similaritySearch( - SearchRequest.query("Spring").topK(5) - .similarityThreshold(0.5d)); + SearchRequest.builder().query("Spring").topK(5) + .similarityThreshold(0.5d).build()); ---- diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mariadb.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mariadb.adoc index e77a55b9d..cde2b2dce 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mariadb.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mariadb.adoc @@ -72,7 +72,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[mariadbvector-properties]] @@ -182,11 +182,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -195,13 +195,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author", "john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: These filter expressions are automatically converted into the equivalent MariaDB JSON path expressions. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc index 754349ee7..f900a427b 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc @@ -85,7 +85,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- === Manual Configuration @@ -136,11 +136,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -149,13 +149,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author","john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: These filter expressions are converted into the equivalent Milvus filters. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mongodb.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mongodb.adoc index f27bc78fe..8d9452d6b 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mongodb.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/mongodb.adoc @@ -70,7 +70,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[mongodbvector-properties]] @@ -174,11 +174,11 @@ For example, you can use either the text expression language: [source,java] ---- -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(5) .similarityThreshold(0.7) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -187,13 +187,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(5) .similarityThreshold(0.7) .filterExpression(b.and( b.in("author", "john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into the proprietary MongoDB Atlas filter expressions. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc index a86fac6e6..0b7e55966 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc @@ -71,7 +71,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[neo4jvector-properties]] @@ -202,11 +202,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'")); + .filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -215,13 +215,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author", "john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into the proprietary Neo4j `WHERE` link:https://neo4j.com/developer/cypher/filtering-query-results/[filter expressions]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/opensearch.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/opensearch.adoc index 4bb3e02da..f209000a1 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/opensearch.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/opensearch.adoc @@ -77,7 +77,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.build().query("Spring").topK(5).build()); ---- === Configuration Properties @@ -203,11 +203,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'")); + .filterExpression("author in ['john', 'jill'] && 'article_type' == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -216,13 +216,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author", "john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into the proprietary OpenSearch link:https://opensearch.org/docs/latest/query-dsl/full-text/query-string/[Query string query]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/oracle.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/oracle.adoc index 0bfb151a7..e3e8928ff 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/oracle.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/oracle.adoc @@ -91,7 +91,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[oracle-properties]] @@ -128,11 +128,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() + SearchRequest.builder() .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -141,13 +141,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author","john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: These filter expressions are converted into the equivalent `OracleVectorStore` filters. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc index 8eda3ff6e..f2b70d63e 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc @@ -127,7 +127,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[pgvector-properties]] @@ -164,11 +164,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -177,13 +177,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author","john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: These filter expressions are converted into PostgreSQL JSON path expressions for efficient metadata filtering. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pinecone.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pinecone.adoc index 3a6510e66..ece6ec25f 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pinecone.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pinecone.adoc @@ -96,7 +96,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- === Configuration properties @@ -127,11 +127,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -140,13 +140,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author","john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: These filter expressions are converted into the equivalent Pinecone filters. @@ -233,7 +233,7 @@ And finally, retrieve documents similar to a query: [source,java] ---- -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5).build()); ---- If all goes well, you should retrieve the document containing the text "Spring AI rocks!!". diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/qdrant.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/qdrant.adoc index 0a484d51a..745ba8aa2 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/qdrant.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/qdrant.adoc @@ -63,7 +63,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[qdrant-vectorstore-properties]] @@ -172,11 +172,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("author in ['john', 'jill'] && article_type == 'blog'")); + .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -185,13 +185,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("author", "john", "jill"), - b.eq("article_type", "blog")).build())); + b.eq("article_type", "blog")).build()).build()); ---- NOTE: These (portable) filter expressions get automatically converted into the proprietary Qdrant link:https://qdrant.tech/documentation/concepts/filtering/[filter expressions]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/redis.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/redis.adoc index fdd6dbd80..03b5ec07d 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/redis.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/redis.adoc @@ -70,7 +70,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = this.vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- [[redisvector-properties]] @@ -114,11 +114,11 @@ For example, you can use either the text expression language: [source,java] ---- -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("country in ['UK', 'NL'] && year >= 2020")); + .filterExpression("country in ['UK', 'NL'] && year >= 2020").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -127,13 +127,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("country", "UK", "NL"), - b.gte("year", 2020)).build())); + b.gte("year", 2020)).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into link:https://redis.io/docs/interact/search-and-query/query/[Redis search queries]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/typesense.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/typesense.adoc index f419384c2..42cd08c04 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/typesense.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/typesense.adoc @@ -60,7 +60,7 @@ List documents = List.of( vectorStore.add(documents); // Retrieve documents similar to a query -List results = vectorStore.similaritySearch(SearchRequest.query("Spring").topK(5)); +List results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build()); ---- === Configuration Properties @@ -187,11 +187,11 @@ For example you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("country in ['UK', 'NL'] && year >= 2020")); + .filterExpression("country in ['UK', 'NL'] && year >= 2020").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -200,13 +200,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("country", "UK", "NL"), - b.gte("year", 2020)).build())); + b.gte("year", 2020)).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into link:https://typesense.org/docs/0.24.0/api/search.html#filter-parameters[Typesense Search Filters]. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/weaviate.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/weaviate.adoc index e6493961c..e4d93a4da 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/weaviate.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/weaviate.adoc @@ -141,11 +141,11 @@ For example, you can use either the text expression language: [source,java] ---- vectorStore.similaritySearch( - SearchRequest.defaults() - .queryString("The World") + SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) - .filterExpression("country in ['UK', 'NL'] && year >= 2020")); + .filterExpression("country in ['UK', 'NL'] && year >= 2020").build()); ---- or programmatically using the `Filter.Expression` DSL: @@ -154,13 +154,13 @@ or programmatically using the `Filter.Expression` DSL: ---- FilterExpressionBuilder b = new FilterExpressionBuilder(); -vectorStore.similaritySearch(SearchRequest.defaults() - .queryString("The World") +vectorStore.similaritySearch(SearchRequest.builder() + .query("The World") .topK(TOP_K) .similarityThreshold(SIMILARITY_THRESHOLD) .filterExpression(b.and( b.in("country", "UK", "NL"), - b.gte("year", 2020)).build())); + b.gte("year", 2020)).build()).build()); ---- NOTE: Those (portable) filter expressions get automatically converted into the proprietary Weaviate link:https://weaviate.io/developers/weaviate/api/graphql/filters[where filters].