diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java index c550b131397..40d9c2059b0 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java @@ -106,11 +106,10 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { for (String id : idList) { this.store.remove(id); } - return Optional.of(true); } @Override diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java index 814efc2eaaa..df1a11f614d 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java @@ -59,10 +59,8 @@ default void accept(List documents) { /** * Deletes documents from the vector store. * @param idList list of document ids for which documents will be removed. - * @return Returns true if the documents were successfully deleted. */ - @Nullable - Optional delete(List idList); + void delete(List idList); /** * Deletes documents from the vector store based on filter criteria. diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java index 320f7e95b1d..d4563cc82d4 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java @@ -87,14 +87,13 @@ public void add(List documents) { } @Override - @Nullable - public Optional delete(List deleteDocIds) { + public void delete(List deleteDocIds) { VectorStoreObservationContext observationContext = this .createObservationContextBuilder(VectorStoreObservationContext.Operation.DELETE.value()) .build(); - return VectorStoreObservationDocumentation.AI_VECTOR_STORE + VectorStoreObservationDocumentation.AI_VECTOR_STORE .observation(this.customObservationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext, this.observationRegistry) .observe(() -> this.doDelete(deleteDocIds)); @@ -140,9 +139,8 @@ public List similaritySearch(SearchRequest request) { /** * Perform the actual delete operation. * @param idList the list of document IDs to delete - * @return true if the documents were successfully deleted */ - public abstract Optional doDelete(List idList); + public abstract void doDelete(List idList); /** * Template method for concrete implementations to provide filter-based deletion diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreTests.java index 1aba11dbef5..85fe0b384c6 100644 --- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreTests.java +++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreTests.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -112,8 +113,8 @@ void shouldDeleteDocuments() { @Test void shouldHandleDeleteOfNonexistentDocument() { this.vectorStore.delete(List.of("nonexistent-id")); - // Should not throw exception and return true - assertThat(this.vectorStore.delete(List.of("nonexistent-id")).get()).isTrue(); + // Should not throw exception + assertDoesNotThrow(() -> this.vectorStore.delete(List.of("nonexistent-id"))); } @Test 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 b56b0c1e316..c2181d376a0 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 @@ -271,7 +271,7 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { try { // Convert the list of IDs into bulk delete operations List itemOperations = idList.stream() @@ -285,12 +285,9 @@ public Optional doDelete(List idList) { response.getResponse().getStatusCode())) .doOnError(error -> logger.error("Error deleting document: {}", error.getMessage())) .blockLast(); // This will block until all operations have finished - - return Optional.of(true); } catch (Exception e) { logger.error("Exception while deleting documents: {}", e.getMessage()); - return Optional.of(false); } } diff --git a/vector-stores/spring-ai-azure-store/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java b/vector-stores/spring-ai-azure-store/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java index 867bbff8672..0f86bd10c9f 100644 --- a/vector-stores/spring-ai-azure-store/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java +++ b/vector-stores/spring-ai-azure-store/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java @@ -188,12 +188,9 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List documentIds) { + public void doDelete(List documentIds) { Assert.notNull(documentIds, "The document ID list should not be null."); - if (CollectionUtils.isEmpty(documentIds)) { - return Optional.of(true); // nothing to do; - } final var searchDocumentIds = documentIds.stream().map(documentId -> { SearchDocument searchDocument = new SearchDocument(); @@ -201,18 +198,7 @@ public Optional doDelete(List documentIds) { return searchDocument; }).toList(); - var results = this.searchClient.deleteDocuments(searchDocumentIds); - - boolean resSuccess = true; - - for (IndexingResult result : results.getResults()) { - if (!result.isSucceeded()) { - resSuccess = false; - break; - } - } - - return Optional.of(resSuccess); + this.searchClient.deleteDocuments(searchDocumentIds); } @Override diff --git a/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java b/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java index 12d0591350a..2c7e8275325 100644 --- a/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java +++ b/vector-stores/spring-ai-cassandra-store/src/main/java/org/springframework/ai/vectorstore/cassandra/CassandraVectorStore.java @@ -305,7 +305,7 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { CompletableFuture[] futures = new CompletableFuture[idList.size()]; int i = 0; for (String id : idList) { @@ -314,7 +314,6 @@ public Optional doDelete(List idList) { futures[i++] = this.session.executeAsync(s).toCompletableFuture(); } CompletableFuture.allOf(futures).join(); - return Optional.of(Boolean.TRUE); } @Override @@ -339,13 +338,7 @@ protected void doDelete(Filter.Expression filterExpression) { if (!matchingDocs.isEmpty()) { // Then delete those documents by ID List idsToDelete = matchingDocs.stream().map(Document::getId).collect(Collectors.toList()); - - Optional result = delete(idsToDelete); - - if (result.isPresent() && !result.get()) { - throw new IllegalStateException("Failed to delete some documents"); - } - + delete(idsToDelete); logger.debug("Deleted {} documents matching filter expression", idsToDelete.size()); } } 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 55184744330..2789c7b9b30 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 @@ -158,10 +158,9 @@ public void doAdd(@NonNull List documents) { } @Override - public Optional doDelete(@NonNull List idList) { + public void doDelete(List idList) { Assert.notNull(idList, "Document id list must not be null"); - int status = this.chromaApi.deleteEmbeddings(this.collectionId, new DeleteEmbeddingsRequest(idList)); - return Optional.of(status == 200); + this.chromaApi.deleteEmbeddings(this.collectionId, new DeleteEmbeddingsRequest(idList)); } @Override diff --git a/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStoreIT.java b/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStoreIT.java index 97802d034cb..b0cc8f3d675 100644 --- a/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStoreIT.java +++ b/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaVectorStoreIT.java @@ -88,8 +88,7 @@ public void addAndSearch() { assertThat(resultDoc.getMetadata()).containsKeys("meta2", DocumentMetadata.DISTANCE.value()); // Remove all documents from the store - assertThat(vectorStore.delete(this.documents.stream().map(doc -> doc.getId()).toList())) - .isEqualTo(Optional.of(Boolean.TRUE)); + vectorStore.delete(this.documents.stream().map(doc -> doc.getId()).toList()); List results2 = vectorStore .similaritySearch(SearchRequest.builder().query("Great").topK(1).build()); @@ -118,7 +117,7 @@ public void simpleSearch() { assertThat(resultDoc.getText()).isEqualTo("The sky is blue because of Rayleigh scattering."); // Remove all documents from the store - assertThat(vectorStore.delete(List.of(document.getId()))).isEqualTo(Optional.of(Boolean.TRUE)); + vectorStore.delete(List.of(document.getId())); results = vectorStore.similaritySearch(SearchRequest.builder().query("Why is the sky blue?").build()); assertThat(results).hasSize(0); diff --git a/vector-stores/spring-ai-coherence-store/src/main/java/org/springframework/ai/vectorstore/coherence/CoherenceVectorStore.java b/vector-stores/spring-ai-coherence-store/src/main/java/org/springframework/ai/vectorstore/coherence/CoherenceVectorStore.java index 32fdd60fcf7..5caa0a3803b 100644 --- a/vector-stores/spring-ai-coherence-store/src/main/java/org/springframework/ai/vectorstore/coherence/CoherenceVectorStore.java +++ b/vector-stores/spring-ai-coherence-store/src/main/java/org/springframework/ai/vectorstore/coherence/CoherenceVectorStore.java @@ -178,21 +178,15 @@ public void doAdd(final List documents) { } @Override - public Optional doDelete(final List idList) { + public void doDelete(final List idList) { var chunkIds = idList.stream().map(this::toChunkId).toList(); - Map results = this.documentChunks.invokeAll(chunkIds, entry -> { + this.documentChunks.invokeAll(chunkIds, entry -> { if (entry.isPresent()) { entry.remove(false); return true; } return false; }); - for (boolean r : results.values()) { - if (!r) { - return Optional.of(false); - } - } - return Optional.of(true); } @Override diff --git a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java index 377ce78dcbf..c8d704ffacb 100644 --- a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java +++ b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java @@ -209,7 +209,7 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { BulkRequest.Builder bulkRequestBuilder = new BulkRequest.Builder(); // For the index to be present, either it must be pre-created or set the // initializeSchema to true. @@ -219,7 +219,6 @@ public Optional doDelete(List idList) { for (String id : idList) { bulkRequestBuilder.operations(op -> op.delete(idx -> idx.index(this.options.getIndexName()).id(id))); } - return Optional.of(bulkRequest(bulkRequestBuilder.build()).errors()); } @Override 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 37fc9383310..a0f1eee9459 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 @@ -231,7 +231,7 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { try { this.client.method(HttpMethod.DELETE) .uri("/" + this.indexName + EMBEDDINGS) @@ -242,9 +242,7 @@ public Optional doDelete(List idList) { } catch (Exception e) { logger.warn("Error removing embedding: {}", e.getMessage(), e); - return Optional.of(false); } - return Optional.of(true); } @Override diff --git a/vector-stores/spring-ai-hanadb-store/src/main/java/org/springframework/ai/vectorstore/hanadb/HanaCloudVectorStore.java b/vector-stores/spring-ai-hanadb-store/src/main/java/org/springframework/ai/vectorstore/hanadb/HanaCloudVectorStore.java index e5722ad6ac6..3e0a3fec77e 100644 --- a/vector-stores/spring-ai-hanadb-store/src/main/java/org/springframework/ai/vectorstore/hanadb/HanaCloudVectorStore.java +++ b/vector-stores/spring-ai-hanadb-store/src/main/java/org/springframework/ai/vectorstore/hanadb/HanaCloudVectorStore.java @@ -126,10 +126,9 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { int deleteCount = this.repository.deleteEmbeddingsById(this.tableName, idList); logger.info("{} embeddings deleted", deleteCount); - return Optional.of(deleteCount == idList.size()); } public int purgeEmbeddings() { diff --git a/vector-stores/spring-ai-mariadb-store/src/main/java/org/springframework/ai/vectorstore/mariadb/MariaDBVectorStore.java b/vector-stores/spring-ai-mariadb-store/src/main/java/org/springframework/ai/vectorstore/mariadb/MariaDBVectorStore.java index 145f48773fb..383f502f907 100644 --- a/vector-stores/spring-ai-mariadb-store/src/main/java/org/springframework/ai/vectorstore/mariadb/MariaDBVectorStore.java +++ b/vector-stores/spring-ai-mariadb-store/src/main/java/org/springframework/ai/vectorstore/mariadb/MariaDBVectorStore.java @@ -318,15 +318,13 @@ private String toJson(Map map) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { int updateCount = 0; for (String id : idList) { int count = this.jdbcTemplate.update( String.format("DELETE FROM %s WHERE %s = ?", getFullyQualifiedTableName(), this.idFieldName), id); updateCount = updateCount + count; } - - return Optional.of(updateCount == idList.size()); } @Override diff --git a/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStore.java b/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStore.java index 326d7ea1d9b..a8bbe4e434d 100644 --- a/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStore.java +++ b/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStore.java @@ -274,7 +274,7 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { Assert.notNull(idList, "Document id list must not be null"); String deleteExpression = String.format("%s in [%s]", this.idFieldName, @@ -290,8 +290,6 @@ public Optional doDelete(List idList) { if (deleteCount != idList.size()) { logger.warn(String.format("Deleted only %s entries from requested %s ", deleteCount, idList.size())); } - - return Optional.of(status.getStatus() == Status.Success.getCode()); } @Override diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/mongodb/atlas/MongoDBAtlasVectorStore.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/mongodb/atlas/MongoDBAtlasVectorStore.java index 1be8edc4887..c6b515aa60f 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/mongodb/atlas/MongoDBAtlasVectorStore.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/mongodb/atlas/MongoDBAtlasVectorStore.java @@ -268,13 +268,9 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { Query query = new Query(org.springframework.data.mongodb.core.query.Criteria.where(ID_FIELD_NAME).in(idList)); - - var deleteRes = this.mongoTemplate.remove(query, this.collectionName); - long deleteCount = deleteRes.getDeletedCount(); - - return Optional.of(deleteCount == idList.size()); + this.mongoTemplate.remove(query, this.collectionName); } @Override diff --git a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStore.java b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStore.java index 1caccfbd425..45dc727e73e 100644 --- a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStore.java +++ b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStore.java @@ -221,20 +221,19 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { try (var session = this.driver.session(this.sessionConfig)) { // Those queries with internal, cypher based transaction management cannot be // run with executeWrite - var summary = session + session .run(""" MATCH (n:%s) WHERE n.%s IN $ids CALL { WITH n DETACH DELETE n } IN TRANSACTIONS OF $transactionSize ROWS """.formatted(this.label, this.idProperty), Map.of("ids", idList, "transactionSize", DEFAULT_TRANSACTION_SIZE)) .consume(); - return Optional.of(idList.size() == summary.counters().nodesDeleted()); } } diff --git a/vector-stores/spring-ai-opensearch-store/src/main/java/org/springframework/ai/vectorstore/opensearch/OpenSearchVectorStore.java b/vector-stores/spring-ai-opensearch-store/src/main/java/org/springframework/ai/vectorstore/opensearch/OpenSearchVectorStore.java index a9953c93b32..f0d8ab2177a 100644 --- a/vector-stores/spring-ai-opensearch-store/src/main/java/org/springframework/ai/vectorstore/opensearch/OpenSearchVectorStore.java +++ b/vector-stores/spring-ai-opensearch-store/src/main/java/org/springframework/ai/vectorstore/opensearch/OpenSearchVectorStore.java @@ -217,12 +217,11 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { BulkRequest.Builder bulkRequestBuilder = new BulkRequest.Builder(); for (String id : idList) { bulkRequestBuilder.operations(op -> op.delete(idx -> idx.index(this.index).id(id))); } - return Optional.of(bulkRequest(bulkRequestBuilder.build()).errors()); } private BulkResponse bulkRequest(BulkRequest bulkRequest) { diff --git a/vector-stores/spring-ai-oracle-store/src/main/java/org/springframework/ai/vectorstore/oracle/OracleVectorStore.java b/vector-stores/spring-ai-oracle-store/src/main/java/org/springframework/ai/vectorstore/oracle/OracleVectorStore.java index 143eebaaab7..bf9e30ce4dd 100644 --- a/vector-stores/spring-ai-oracle-store/src/main/java/org/springframework/ai/vectorstore/oracle/OracleVectorStore.java +++ b/vector-stores/spring-ai-oracle-store/src/main/java/org/springframework/ai/vectorstore/oracle/OracleVectorStore.java @@ -286,7 +286,7 @@ private double[] normalize(final double[] v) { } @Override - public Optional doDelete(final List idList) { + public void doDelete(final List idList) { final String sql = String.format("delete from %s where id=?", this.tableName); final int[] argTypes = { Types.VARCHAR }; @@ -297,19 +297,15 @@ public Optional doDelete(final List idList) { final int[] deleteCounts = this.jdbcTemplate.batchUpdate(sql, batchArgs, argTypes); - int deleteCount = 0; for (int detailedResult : deleteCounts) { switch (detailedResult) { case Statement.EXECUTE_FAILED: break; case 1: case Statement.SUCCESS_NO_INFO: - deleteCount++; break; } } - - return Optional.of(deleteCount == idList.size()); } @Override diff --git a/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/pgvector/PgVectorStore.java b/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/pgvector/PgVectorStore.java index d3a46054697..8cd7c6e65bc 100644 --- a/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/pgvector/PgVectorStore.java +++ b/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/pgvector/PgVectorStore.java @@ -305,15 +305,13 @@ private String toJson(Map map) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { int updateCount = 0; for (String id : idList) { int count = this.jdbcTemplate.update("DELETE FROM " + getFullyQualifiedTableName() + " WHERE id = ?", UUID.fromString(id)); updateCount = updateCount + count; } - - return Optional.of(updateCount == idList.size()); } @Override diff --git a/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/pgvector/PgVectorStoreIT.java b/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/pgvector/PgVectorStoreIT.java index 59d6ed50c27..009cefe7d4d 100644 --- a/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/pgvector/PgVectorStoreIT.java +++ b/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/pgvector/PgVectorStoreIT.java @@ -395,9 +395,7 @@ public void deleteByIds() { assertThat(results).hasSize(3); // Delete two documents by ID - Optional deleteResult = vectorStore.delete(List.of(bgDocument.getId(), nlDocument.getId())); - - assertThat(deleteResult).isPresent().contains(true); + vectorStore.delete(List.of(bgDocument.getId(), nlDocument.getId())); // Verify deletion results = vectorStore.similaritySearch(searchRequest); diff --git a/vector-stores/spring-ai-pinecone-store/src/main/java/org/springframework/ai/vectorstore/pinecone/PineconeVectorStore.java b/vector-stores/spring-ai-pinecone-store/src/main/java/org/springframework/ai/vectorstore/pinecone/PineconeVectorStore.java index 04848383c42..2d5b018d1db 100644 --- a/vector-stores/spring-ai-pinecone-store/src/main/java/org/springframework/ai/vectorstore/pinecone/PineconeVectorStore.java +++ b/vector-stores/spring-ai-pinecone-store/src/main/java/org/springframework/ai/vectorstore/pinecone/PineconeVectorStore.java @@ -224,9 +224,8 @@ private Value contentValue(Document document) { * Deletes a list of documents by their IDs based on the namespace. * @param documentIds The list of document IDs to be deleted. * @param namespace The namespace of the document IDs. - * @return An optional boolean indicating the deletion status. */ - public Optional delete(List documentIds, String namespace) { + public void delete(List documentIds, String namespace) { DeleteRequest deleteRequest = DeleteRequest.newBuilder() .setNamespace(namespace) // ignored for free tier. @@ -235,19 +234,15 @@ public Optional delete(List documentIds, String namespace) { .build(); this.pineconeConnection.getBlockingStub().delete(deleteRequest); - - // The Pinecone delete API does not provide deletion status info. - return Optional.of(true); } /** * Deletes a list of documents by their IDs. * @param documentIds The list of document IDs to be deleted. - * @return An optional boolean indicating the deletion status. */ @Override - public Optional doDelete(List documentIds) { - return delete(documentIds, this.pineconeNamespace); + public void doDelete(List documentIds) { + delete(documentIds, this.pineconeNamespace); } public List similaritySearch(SearchRequest request, String namespace) { @@ -309,13 +304,7 @@ protected void doDelete(Filter.Expression filterExpression) { if (!matchingDocs.isEmpty()) { // Then delete those documents by ID List idsToDelete = matchingDocs.stream().map(Document::getId).collect(Collectors.toList()); - - Optional result = delete(idsToDelete, this.pineconeNamespace); - - if (result.isPresent() && !result.get()) { - throw new IllegalStateException("Failed to delete some documents"); - } - + delete(idsToDelete, this.pineconeNamespace); logger.debug("Deleted {} documents matching filter expression", idsToDelete.size()); } } diff --git a/vector-stores/spring-ai-qdrant-store/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java b/vector-stores/spring-ai-qdrant-store/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java index 4bff2ce9c21..5ae5c6f2e54 100644 --- a/vector-stores/spring-ai-qdrant-store/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java +++ b/vector-stores/spring-ai-qdrant-store/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java @@ -198,20 +198,16 @@ public void doAdd(List documents) { /** * Deletes a list of documents by their IDs. * @param documentIds The list of document IDs to be deleted. - * @return An optional boolean indicating the deletion status. */ @Override - public Optional doDelete(List documentIds) { + public void doDelete(List documentIds) { try { List ids = documentIds.stream() .map(id -> io.qdrant.client.PointIdFactory.id(UUID.fromString(id))) .toList(); - var result = this.qdrantClient.deleteAsync(this.collectionName, ids) - .get() - .getStatus() == UpdateStatus.Completed; - return Optional.of(result); + this.qdrantClient.deleteAsync(this.collectionName, ids).get(); } - catch (InterruptedException | ExecutionException | IllegalArgumentException e) { + catch (Exception e) { throw new RuntimeException(e); } } diff --git a/vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisVectorStore.java b/vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisVectorStore.java index b3a396072ca..67d033fb2cf 100644 --- a/vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisVectorStore.java +++ b/vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisVectorStore.java @@ -280,7 +280,7 @@ private String key(String id) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { try (Pipeline pipeline = this.jedis.pipelined()) { for (String id : idList) { pipeline.jsonDel(key(id)); @@ -291,9 +291,7 @@ public Optional doDelete(List idList) { if (logger.isErrorEnabled()) { logger.error("Could not delete document: {}", errResponse.get()); } - return Optional.of(false); } - return Optional.of(true); } } diff --git a/vector-stores/spring-ai-typesense-store/src/main/java/org/springframework/ai/vectorstore/typesense/TypesenseVectorStore.java b/vector-stores/spring-ai-typesense-store/src/main/java/org/springframework/ai/vectorstore/typesense/TypesenseVectorStore.java index 765943c3a20..21e14063cc1 100644 --- a/vector-stores/spring-ai-typesense-store/src/main/java/org/springframework/ai/vectorstore/typesense/TypesenseVectorStore.java +++ b/vector-stores/spring-ai-typesense-store/src/main/java/org/springframework/ai/vectorstore/typesense/TypesenseVectorStore.java @@ -167,7 +167,7 @@ public void doAdd(List documents) { } @Override - public Optional doDelete(List idList) { + public void doDelete(List idList) { DeleteDocumentsParameters deleteDocumentsParameters = new DeleteDocumentsParameters(); deleteDocumentsParameters.filterBy(DOC_ID_FIELD_NAME + ":=[" + String.join(",", idList) + "]"); @@ -180,12 +180,9 @@ public Optional doDelete(List idList) { if (deletedDocs < idList.size()) { logger.warn("Failed to delete all documents"); } - - return Optional.of(deletedDocs > 0); } catch (Exception e) { logger.error("Failed to delete documents", e); - return Optional.of(Boolean.FALSE); } } diff --git a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java index ab1f7b7bb51..6628d2eff52 100644 --- a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java +++ b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java @@ -273,7 +273,7 @@ private WeaviateObject toWeaviateObject(Document document, List docume } @Override - public Optional doDelete(List documentIds) { + public void doDelete(List documentIds) { Result result = this.weaviateClient.batch() .objectsBatchDeleter() @@ -294,8 +294,6 @@ public Optional doDelete(List documentIds) { .collect(Collectors.joining(",")); throw new RuntimeException("Failed to delete documents because: \n" + errorMessages); } - - return Optional.of(!result.hasErrors()); } @Override @@ -317,11 +315,7 @@ protected void doDelete(Filter.Expression filterExpression) { if (!matchingDocs.isEmpty()) { List idsToDelete = matchingDocs.stream().map(Document::getId).collect(Collectors.toList()); - Optional result = delete(idsToDelete); - - if (result.isPresent() && !result.get()) { - throw new IllegalStateException("Failed to delete some documents"); - } + delete(idsToDelete); logger.debug("Deleted {} documents matching filter expression", idsToDelete.size()); }