indexDefinition) {
+ this.id = id;
+ this.status = status;
+ this.indexDefinition = Lazy.of(indexDefinition);
+ }
+
+ public static SearchIndexInfo parse(String source) {
+ return of(Document.parse(source));
+ }
+
+ public static SearchIndexInfo of(Document indexDocument) {
+
+ Object id = indexDocument.get("id");
+ SearchIndexStatus status = SearchIndexStatus.valueOf(indexDocument.get("status", "DOES_NOT_EXIST"));
+
+ return new SearchIndexInfo(id, status, () -> readIndexDefinition(indexDocument));
+ }
+
+ /**
+ * The id of the index. Can be {@literal null}, eg. for an index not yet created.
+ *
+ * @return can be {@literal null}.
+ */
+ @Nullable
+ public Object getId() {
+ return id;
+ }
+
+ /**
+ * @return the current status of the index.
+ */
+ public SearchIndexStatus getStatus() {
+ return status;
+ }
+
+ /**
+ * @return the current index definition.
+ */
+ public SearchIndexDefinition getIndexDefinition() {
+ return indexDefinition.get();
+ }
+
+ private static SearchIndexDefinition readIndexDefinition(Document document) {
+
+ String type = document.get("type", "search");
+ if (type.equals("vectorSearch")) {
+ return VectorIndex.of(document);
+ }
+
+ return new SearchIndexDefinition() {
+
+ @Override
+ public String getName() {
+ return document.getString("name");
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ @Override
+ public Document getDefinition(@Nullable TypeInformation> entity,
+ @Nullable MappingContext extends MongoPersistentEntity>, MongoPersistentProperty> mappingContext) {
+ if (document.containsKey("latestDefinition")) {
+ return document.get("latestDefinition", new Document());
+ }
+ return document.get("definition", new Document());
+ }
+
+ @Override
+ public String toString() {
+ return getDefinition(null, null).toJson();
+ }
+ };
+ }
+}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperations.java
index 24b7bc1f30..d68b547a34 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperations.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperations.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2024. the original author or authors.
+ * Copyright 2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.index;
-import java.util.List;
+import org.springframework.dao.DataAccessException;
/**
* Search Index operations on a collection for Atlas Search.
@@ -23,52 +23,65 @@
* @author Christoph Strobl
* @author Mark Paluch
* @since 4.5
+ * @see VectorIndex
*/
public interface SearchIndexOperations {
/**
- * Ensure that an index for the provided {@link SearchIndexDefinition} exists for the collection indicated by the
- * entity class. If not it will be created.
+ * Create the index for the given {@link SearchIndexDefinition} in the collection indicated by the entity class.
*
* @param indexDefinition must not be {@literal null}.
* @return the index name.
*/
- String ensureIndex(SearchIndexDefinition indexDefinition);
+ // TODO: keep or just go with createIndex?
+ default String ensureIndex(SearchIndexDefinition indexDefinition) {
+ return createIndex(indexDefinition);
+ }
/**
- * Alters the search {@code index}.
+ * Create the index for the given {@link SearchIndexDefinition} in the collection indicated by the entity class.
+ *
+ * @param indexDefinition must not be {@literal null}.
+ * @return the index name.
+ */
+ String createIndex(SearchIndexDefinition indexDefinition);
+
+ /**
+ * Alters the search index matching the index {@link SearchIndexDefinition#getName() name}.
*
- * Note that Atlas Search does not support updating Vector Search Indices resulting in
- * {@link UnsupportedOperationException}.
+ * Atlas Search might not support updating indices which raises a {@link DataAccessException}.
*
- * @param index the index definition.
+ * @param indexDefinition the index definition.
*/
- void updateIndex(SearchIndexDefinition index);
+ // TODO: keep or remove since it does not work reliably?
+ void updateIndex(SearchIndexDefinition indexDefinition);
/**
- * Check whether an index with the {@code name} exists.
+ * Check whether an index with the given {@code indexName} exists for the collection indicated by the entity class. To
+ * ensure an existing index is queryable it is recommended to check its {@link #status(String) status}.
*
- * @param name name of index to check for presence.
+ * @param indexName name of index to check for presence.
* @return {@literal true} if the index exists; {@literal false} otherwise.
*/
- boolean exists(String name);
+ boolean exists(String indexName);
/**
- * Drops an index from this collection.
+ * Check the actual {@link SearchIndexStatus status} of an index.
*
- * @param name name of index to drop.
+ * @param indexName name of index to get the status for.
+ * @return the current status of the index or {@link SearchIndexStatus#DOES_NOT_EXIST} if the index cannot be found.
*/
- void dropIndex(String name);
+ SearchIndexStatus status(String indexName);
/**
- * Drops all search indices from this collection.
+ * Drops an index from the collection indicated by the entity class.
+ *
+ * @param indexName name of index to drop.
*/
- void dropAllIndexes();
+ void dropIndex(String indexName);
/**
- * Returns the index information on the collection.
- *
- * @return index information on the collection
+ * Drops all search indices from the collection indicated by the entity class.
*/
- List getIndexInfo();
+ void dropAllIndexes();
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperationsProvider.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperationsProvider.java
index 389b666a23..ee87c8d61e 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperationsProvider.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexOperationsProvider.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2024. the original author or authors.
+ * Copyright 2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexStatus.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexStatus.java
new file mode 100644
index 0000000000..91143d73c6
--- /dev/null
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndexStatus.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2025. the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.mongodb.core.index;
+
+/**
+ * Representation of different conditions a search index can be in.
+ *
+ * @author Christoph Strobl
+ * @since 4.5
+ */
+public enum SearchIndexStatus {
+
+ /** building or re-building the index - might be queryable */
+ BUILDING,
+
+ /** nothing to be seen here - not queryable */
+ DOES_NOT_EXIST,
+
+ /** will cease to exist - no longer queryable */
+ DELETING,
+
+ /** well, this one is broken - not queryable */
+ FAILED,
+
+ /** busy with other things, check back later - not queryable */
+ PENDING,
+
+ /** ask me anything - queryable */
+ READY,
+
+ /** ask me anything about outdated data - still queryable */
+ STALE
+}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/VectorIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/VectorIndex.java
index 9c56989856..20cf2a8ff1 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/VectorIndex.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/VectorIndex.java
@@ -36,7 +36,6 @@
import java.util.function.Consumer;
import org.bson.Document;
-
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
@@ -45,9 +44,10 @@
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
/**
- * {@link IndexDefinition} for creating MongoDB
+ * {@link SearchIndexDefinition} for creating MongoDB
* Vector Index required to
* run {@code $vectorSearch} queries.
*
@@ -58,7 +58,7 @@
public class VectorIndex implements SearchIndexDefinition {
private final String name;
- private final List