From 8c2db3c2edbf1f6209ebfd562eb4235ca9f21150 Mon Sep 17 00:00:00 2001 From: Filip Hrisafov Date: Thu, 19 Jun 2025 15:58:39 +0200 Subject: [PATCH] Remove `@Nullable` from VectorStore similaritySearch The VectorStore#similaritySearch methods never return null. There is a data flow issue in the AbstractObservationVectorStore. However, that's only because Micrometer Observation#observe is marked as `@Nullable`, but the value returned is actually the value that the passed supplier returns, which is on control of Spring AI and is never null Signed-off-by: Filip Hrisafov --- .../org/springframework/ai/vectorstore/VectorStore.java | 3 --- .../observation/AbstractObservationVectorStore.java | 4 +++- .../ai/vectorstore/cosmosdb/CosmosDBVectorStore.java | 4 +--- .../ai/chroma/vectorstore/ChromaVectorStore.java | 6 ++---- .../ai/vectorstore/gemfire/GemFireVectorStore.java | 1 - 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/VectorStore.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/VectorStore.java index df1a11f614d..ec9a6601c47 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/VectorStore.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/VectorStore.java @@ -27,7 +27,6 @@ import org.springframework.ai.vectorstore.filter.Filter; import org.springframework.ai.vectorstore.observation.DefaultVectorStoreObservationConvention; import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -91,7 +90,6 @@ default void delete(String filterExpression) { * topK, similarity threshold and metadata filter expressions. * @return Returns documents th match the query request conditions. */ - @Nullable List similaritySearch(SearchRequest request); /** @@ -101,7 +99,6 @@ default void delete(String filterExpression) { * @return Returns a list of documents that have embeddings similar to the query text * embedding. */ - @Nullable default List similaritySearch(String query) { return this.similaritySearch(SearchRequest.builder().query(query).build()); } diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java index ca3c3ae9185..52c8106a48e 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java @@ -111,7 +111,9 @@ public void delete(Filter.Expression filterExpression) { } @Override - @Nullable + // Micrometer Observation#observe returns the value of the Supplier, which is never + // null + @SuppressWarnings("DataFlowIssue") public List similaritySearch(SearchRequest request) { VectorStoreObservationContext searchObservationContext = this diff --git a/vector-stores/spring-ai-azure-cosmos-db-store/src/main/java/org/springframework/ai/vectorstore/cosmosdb/CosmosDBVectorStore.java b/vector-stores/spring-ai-azure-cosmos-db-store/src/main/java/org/springframework/ai/vectorstore/cosmosdb/CosmosDBVectorStore.java index ca2a817001a..ccf587b45ce 100644 --- a/vector-stores/spring-ai-azure-cosmos-db-store/src/main/java/org/springframework/ai/vectorstore/cosmosdb/CosmosDBVectorStore.java +++ b/vector-stores/spring-ai-azure-cosmos-db-store/src/main/java/org/springframework/ai/vectorstore/cosmosdb/CosmosDBVectorStore.java @@ -434,15 +434,13 @@ public List doSimilaritySearch(SearchRequest request) { } // Convert JsonNode to Document - List docs = documents.stream() + return documents.stream() .map(doc -> Document.builder() .id(doc.get("id").asText()) .text(doc.get("content").asText()) .metadata(docFields) .build()) .collect(Collectors.toList()); - - return docs != null ? docs : List.of(); } catch (Exception e) { logger.error("Error during similarity search: {}", e.getMessage()); diff --git a/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStore.java b/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStore.java index a6f6628f6c6..8421058c24c 100644 --- a/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStore.java +++ b/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStore.java @@ -45,7 +45,6 @@ import org.springframework.ai.vectorstore.observation.AbstractObservationVectorStore; import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext; import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -148,7 +147,7 @@ public void afterPropertiesSet() throws Exception { } @Override - public void doAdd(@NonNull List documents) { + public void doAdd(List documents) { Assert.notNull(documents, "Documents must not be null"); if (CollectionUtils.isEmpty(documents)) { return; @@ -202,8 +201,7 @@ protected void doDelete(Filter.Expression expression) { } @Override - @NonNull - public List doSimilaritySearch(@NonNull SearchRequest request) { + public List doSimilaritySearch(SearchRequest request) { String query = request.getQuery(); Assert.notNull(query, "Query string must not be null"); diff --git a/vector-stores/spring-ai-gemfire-store/src/main/java/org/springframework/ai/vectorstore/gemfire/GemFireVectorStore.java b/vector-stores/spring-ai-gemfire-store/src/main/java/org/springframework/ai/vectorstore/gemfire/GemFireVectorStore.java index 6d90043fde4..7cda95ce430 100644 --- a/vector-stores/spring-ai-gemfire-store/src/main/java/org/springframework/ai/vectorstore/gemfire/GemFireVectorStore.java +++ b/vector-stores/spring-ai-gemfire-store/src/main/java/org/springframework/ai/vectorstore/gemfire/GemFireVectorStore.java @@ -243,7 +243,6 @@ public void doDelete(List idList) { } @Override - @Nullable public List doSimilaritySearch(SearchRequest request) { if (request.hasFilterExpression()) { throw new UnsupportedOperationException("GemFire currently does not support metadata filter expressions.");