From 24da2efc86bcce0bed951b7f8effe9fdf92270fb Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Thu, 4 Jul 2024 14:33:45 +0100 Subject: [PATCH] Fix IndexAlreadyExists exception for spring-ai-mongodb-atlas-store In testing the docker mongodb/atlas container doesn't throw an exception when calling `mongoTemplate.executeCommand({"createSearchIndexes": ...});`. However, when using the Atlas service it does and throws a `IndexAlreadyExists` exception. Added error handling for error code 68 or error code name `IndexAlreadyExists`. See: https://www.mongodb.com/docs/manual/reference/error-codes/ Fixes #910 --- .../vectorstore/MongoDBAtlasVectorStore.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java index d3a1e14ff..678ab8b7f 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java +++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java @@ -23,9 +23,11 @@ import java.util.Optional; import com.mongodb.BasicDBObject; +import com.mongodb.MongoCommandException; import org.springframework.ai.document.Document; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.mongodb.UncategorizedMongoDbException; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.query.Criteria; @@ -56,6 +58,10 @@ public class MongoDBAtlasVectorStore implements VectorStore, InitializingBean { private static final int DEFAULT_NUM_CANDIDATES = 200; + private static final int INDEX_ALREADY_EXISTS_ERROR_CODE = 68; + + private static final String INDEX_ALREADY_EXISTS_ERROR_CODE_NAME = "IndexAlreadyExists"; + private final MongoTemplate mongoTemplate; private final EmbeddingModel embeddingModel; @@ -90,14 +96,31 @@ public class MongoDBAtlasVectorStore implements VectorStore, InitializingBean { if (!mongoTemplate.collectionExists(this.config.collectionName)) { mongoTemplate.createCollection(this.config.collectionName); } - // Create search index, command doesn't do anything if already existing - mongoTemplate.executeCommand(createSearchIndex()); + // Create search index + createSearchIndex(); + } + + private void createSearchIndex() { + try { + mongoTemplate.executeCommand(createSearchIndexDefinition()); + } + catch (UncategorizedMongoDbException e) { + Throwable cause = e.getCause(); + if (cause instanceof MongoCommandException commandException) { + // Ignore any IndexAlreadyExists errors + if (INDEX_ALREADY_EXISTS_ERROR_CODE == commandException.getCode() + || INDEX_ALREADY_EXISTS_ERROR_CODE_NAME.equals(commandException.getErrorCodeName())) { + return; + } + } + throw e; + } } /** * Provides the Definition for the search index */ - private org.bson.Document createSearchIndex() { + private org.bson.Document createSearchIndexDefinition() { List vectorFields = new ArrayList<>(); vectorFields.add(new org.bson.Document().append("type", "vector")