Skip to content

Commit 86a73f9

Browse files
sobychackomarkpollack
authored andcommitted
Add vector store delete API ref docs with examples
- Document delete APIs with ID lists and filter expressions - Add versioning use case with metadata-based updates Signed-off-by: Soby Chacko <soby.chacko@broadcom.com>
1 parent 3f0557b commit 86a73f9

File tree

1 file changed

+199
-1
lines changed

1 file changed

+199
-1
lines changed

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs.adoc

Lines changed: 199 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public interface VectorStore extends DocumentWriter {
3535

3636
void add(List<Document> documents);
3737

38-
Optional<Boolean> delete(List<String> idList);
38+
void delete(List<String> idList);
3939

4040
void delete(Filter.Expression filterExpression);
4141

@@ -392,6 +392,204 @@ Consider the following example:
392392
Expression exp = b.and(b.eq("genre", "drama"), b.gte("year", 2020)).build();
393393
----
394394

395+
== Deleting Documents from Vector Store
396+
397+
The Vector Store interface provides multiple methods for deleting documents, allowing you to remove data either by specific document IDs or using filter expressions.
398+
399+
=== Delete by Document IDs
400+
401+
The simplest way to delete documents is by providing a list of document IDs:
402+
403+
[source,java]
404+
----
405+
void delete(List<String> idList);
406+
----
407+
408+
This method removes all documents whose IDs match those in the provided list.
409+
If any ID in the list doesn't exist in the store, it will be ignored.
410+
411+
.Example usage
412+
[source,java]
413+
----
414+
// Create and add document
415+
Document document = new Document("The World is Big",
416+
Map.of("country", "Netherlands"));
417+
vectorStore.add(List.of(document));
418+
419+
// Delete document by ID
420+
vectorStore.delete(List.of(document.getId()));
421+
----
422+
423+
=== Delete by Filter Expression
424+
425+
For more complex deletion criteria, you can use filter expressions:
426+
427+
[source,java]
428+
----
429+
void delete(Filter.Expression filterExpression);
430+
----
431+
432+
This method accepts a `Filter.Expression` object that defines the criteria for which documents should be deleted.
433+
It's particularly useful when you need to delete documents based on their metadata properties.
434+
435+
.Example usage
436+
[source,java]
437+
----
438+
// Create test documents with different metadata
439+
Document bgDocument = new Document("The World is Big",
440+
Map.of("country", "Bulgaria"));
441+
Document nlDocument = new Document("The World is Big",
442+
Map.of("country", "Netherlands"));
443+
444+
// Add documents to the store
445+
vectorStore.add(List.of(bgDocument, nlDocument));
446+
447+
// Delete documents from Bulgaria using filter expression
448+
Filter.Expression filterExpression = new Filter.Expression(
449+
Filter.ExpressionType.EQ,
450+
new Filter.Key("country"),
451+
new Filter.Value("Bulgaria")
452+
);
453+
vectorStore.delete(filterExpression);
454+
455+
// Verify deletion with search
456+
SearchRequest request = SearchRequest.builder()
457+
.query("World")
458+
.filterExpression("country == 'Bulgaria'")
459+
.build();
460+
List<Document> results = vectorStore.similaritySearch(request);
461+
// results will be empty as Bulgarian document was deleted
462+
----
463+
464+
=== Delete by String Filter Expression
465+
466+
For convenience, you can also delete documents using a string-based filter expression:
467+
468+
[source,java]
469+
----
470+
void delete(String filterExpression);
471+
----
472+
473+
This method converts the provided string filter into a `Filter.Expression` object internally.
474+
It's useful when you have filter criteria in string format.
475+
476+
.Example usage
477+
[source,java]
478+
----
479+
// Create and add documents
480+
Document bgDocument = new Document("The World is Big",
481+
Map.of("country", "Bulgaria"));
482+
Document nlDocument = new Document("The World is Big",
483+
Map.of("country", "Netherlands"));
484+
vectorStore.add(List.of(bgDocument, nlDocument));
485+
486+
// Delete Bulgarian documents using string filter
487+
vectorStore.delete("country == 'Bulgaria'");
488+
489+
// Verify remaining documents
490+
SearchRequest request = SearchRequest.builder()
491+
.query("World")
492+
.topK(5)
493+
.build();
494+
List<Document> results = vectorStore.similaritySearch(request);
495+
// results will only contain the Netherlands document
496+
----
497+
498+
=== Error Handling When Calling the Delete API
499+
500+
All deletion methods may throw exceptions in case of errors:
501+
502+
The best practice is to wrap delete operations in try-catch blocks:
503+
504+
.Example usage
505+
[source,java]
506+
----
507+
try {
508+
vectorStore.delete("country == 'Bulgaria'");
509+
}
510+
catch (Exception e) {
511+
logger.error("Invalid filter expression", e);
512+
}
513+
----
514+
515+
=== Document Versioning Use Case
516+
517+
A common scenario is managing document versions where you need to upload a new version of a document while removing the old version. Here's how to handle this using filter expressions:
518+
519+
.Example usage
520+
[source,java]
521+
----
522+
// Create initial document (v1) with version metadata
523+
Document documentV1 = new Document(
524+
"AI and Machine Learning Best Practices",
525+
Map.of(
526+
"docId", "AIML-001",
527+
"version", "1.0",
528+
"lastUpdated", "2024-01-01"
529+
)
530+
);
531+
532+
// Add v1 to the vector store
533+
vectorStore.add(List.of(documentV1));
534+
535+
// Create updated version (v2) of the same document
536+
Document documentV2 = new Document(
537+
"AI and Machine Learning Best Practices - Updated",
538+
Map.of(
539+
"docId", "AIML-001",
540+
"version", "2.0",
541+
"lastUpdated", "2024-02-01"
542+
)
543+
);
544+
545+
// First, delete the old version using filter expression
546+
Filter.Expression deleteOldVersion = new Filter.Expression(
547+
Filter.ExpressionType.AND,
548+
Arrays.asList(
549+
new Filter.Expression(
550+
Filter.ExpressionType.EQ,
551+
new Filter.Key("docId"),
552+
new Filter.Value("AIML-001")
553+
),
554+
new Filter.Expression(
555+
Filter.ExpressionType.EQ,
556+
new Filter.Key("version"),
557+
new Filter.Value("1.0")
558+
)
559+
)
560+
);
561+
vectorStore.delete(deleteOldVersion);
562+
563+
// Add the new version
564+
vectorStore.add(List.of(documentV2));
565+
566+
// Verify only v2 exists
567+
SearchRequest request = SearchRequest.builder()
568+
.query("AI and Machine Learning")
569+
.filterExpression("docId == 'AIML-001'")
570+
.build();
571+
List<Document> results = vectorStore.similaritySearch(request);
572+
// results will contain only v2 of the document
573+
----
574+
575+
You can also accomplish the same using the string filter expression:
576+
577+
.Example usage
578+
[source,java]
579+
----
580+
// Delete old version using string filter
581+
vectorStore.delete("docId == 'AIML-001' AND version == '1.0'");
582+
583+
// Add new version
584+
vectorStore.add(List.of(documentV2));
585+
----
586+
587+
=== Performance Considerations While Deleting Documents
588+
589+
* Deleting by ID list is generally faster when you know exactly which documents to remove.
590+
* Filter-based deletion may require scanning the index to find matching documents; however, this is vector store implementation-specific.
591+
* Large deletion operations should be batched to avoid overwhelming the system.
592+
* Consider using filter expressions when deleting based on document properties rather than collecting IDs first.
395593

396594
== Understanding Vectors
397595

0 commit comments

Comments
 (0)