Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
*/
public class ChromaVectorStore extends AbstractObservationVectorStore implements InitializingBean {

private static final int DEFAULT_PURGE_BATCH_SIZE = 1000;

private final ChromaApi chromaApi;

private final String tenantName;
Expand Down Expand Up @@ -175,6 +177,44 @@ public void doDelete(List<String> idList) {
new DeleteEmbeddingsRequest(idList));
}

/**
* Deletes all embeddings from the current collection while keeping the collection
* itself intact. Embeddings are deleted in batches by repeatedly fetching the first
* page of ids until the collection is empty.
* <p>
* Note: This method does not support concurrency control. Concurrent writes or
* deletions may result in incomplete deletions or duplicate deletion attempts.
* @return the number of embeddings requested for deletion
* @since 2.0.0-SNAPSHOT
*/
public int purgeEmbeddings() {
int deleteCount = 0;
String collectionId = this.requireCollectionId();
try {
while (true) {
var response = this.chromaApi.getEmbeddings(this.tenantName, this.databaseName, collectionId,
new ChromaApi.GetEmbeddingsRequest(List.of(), Map.of(), DEFAULT_PURGE_BATCH_SIZE, 0,
List.of()));

if (response == null || CollectionUtils.isEmpty(response.ids())) {
return deleteCount;
}
List<String> ids = response.ids();
this.chromaApi.deleteEmbeddings(this.tenantName, this.databaseName, collectionId,
new DeleteEmbeddingsRequest(ids));
deleteCount += ids.size();

if (ids.size() < DEFAULT_PURGE_BATCH_SIZE) {
return deleteCount;
}
}
}
catch (Exception e) {
logger.error("Purge failed: {}", e.getMessage());
throw new IllegalStateException("Failed to purge chroma collection", e);
}
}

@Override
protected void doDelete(Filter.Expression expression) {
Assert.notNull(expression, "Filter expression must not be null");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,17 @@ public void searchThresholdTest() {
});
}

@Test
public void purgeEmbeddingsCollection() {
this.contextRunner.run(context -> {
VectorStore vectorStore = context.getBean(VectorStore.class);
vectorStore.add(this.documents);

int deletedCount = ((ChromaVectorStore) vectorStore).purgeEmbeddings();
assertThat(deletedCount).isEqualTo(this.documents.size());
});
}

@SpringBootConfiguration
public static class TestApplication {

Expand Down