diff --git a/driver-core/src/main/com/mongodb/client/model/SearchIndexModel.java b/driver-core/src/main/com/mongodb/client/model/SearchIndexModel.java
index 124be4885c0..2a229e1a579 100644
--- a/driver-core/src/main/com/mongodb/client/model/SearchIndexModel.java
+++ b/driver-core/src/main/com/mongodb/client/model/SearchIndexModel.java
@@ -25,12 +25,14 @@
* A model describing the creation of a single Atlas Search index.
*
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
public final class SearchIndexModel {
@Nullable
private final String name;
private final Bson definition;
+ @Nullable
+ private final SearchIndexType type;
/**
* Construct an instance with the given Atlas Search index mapping definition.
@@ -42,8 +44,7 @@ public final class SearchIndexModel {
* @param definition the search index mapping definition.
*/
public SearchIndexModel(final Bson definition) {
- this.definition = notNull("definition", definition);
- this.name = null;
+ this(null, definition, null);
}
/**
@@ -53,8 +54,21 @@ public SearchIndexModel(final Bson definition) {
* @param definition the search index mapping definition.
*/
public SearchIndexModel(final String name, final Bson definition) {
+ this(name, definition, null);
+ }
+
+ /**
+ * Construct an instance with the given Atlas Search name, index definition, and type.
+ *
+ * @param name the search index name.
+ * @param definition the search index mapping definition.
+ * @param type the search index type.
+ * @since 5.2
+ */
+ public SearchIndexModel(@Nullable final String name, final Bson definition, @Nullable final SearchIndexType type) {
this.definition = notNull("definition", definition);
- this.name = notNull("name", name);
+ this.name = name;
+ this.type = type;
}
/**
@@ -76,11 +90,23 @@ public String getName() {
return name;
}
+ /**
+ * Get the Atlas Search index type.
+ *
+ * @return the search index type.
+ * @since 5.2
+ */
+ @Nullable
+ public SearchIndexType getType() {
+ return type;
+ }
+
@Override
public String toString() {
return "SearchIndexModel{"
+ "name=" + name
+ ", definition=" + definition
+ + ", type=" + (type == null ? "null" : type.toBsonValue())
+ '}';
}
}
diff --git a/driver-core/src/main/com/mongodb/client/model/SearchIndexType.java b/driver-core/src/main/com/mongodb/client/model/SearchIndexType.java
new file mode 100644
index 00000000000..5ed73461a05
--- /dev/null
+++ b/driver-core/src/main/com/mongodb/client/model/SearchIndexType.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008-present MongoDB, Inc.
+ *
+ * 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
+ *
+ * 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 com.mongodb.client.model;
+
+import com.mongodb.annotations.Sealed;
+import org.bson.BsonString;
+import org.bson.BsonValue;
+
+import static com.mongodb.assertions.Assertions.notNull;
+
+/**
+ * This interface represents an Atlas Search Index type, which is utilized for creating specific types of indexes.
+ *
+ * It provides methods for creating and converting Atlas Search Index types to {@link BsonValue}.
+ *
+ *
+ * @mongodb.server.release 6.0
+ * @see SearchIndexModel The model class that utilizes this index type.
+ * @since 5.2
+ */
+@Sealed
+public interface SearchIndexType {
+
+ /**
+ * Returns a {@link SearchIndexType} instance representing the "search" index type.
+ *
+ * @return The requested {@link SearchIndexType}.
+ */
+ static SearchIndexType search() {
+ return new SearchIndexTypeBson(new BsonString("search"));
+ }
+
+ /**
+ * Returns a {@link SearchIndexType} instance representing the "vectorSearch" index type.
+ *
+ * @return The requested {@link SearchIndexType}.
+ */
+ static SearchIndexType vectorSearch() {
+ return new SearchIndexTypeBson(new BsonString("vectorSearch"));
+ }
+
+ /**
+ * Creates a {@link SearchIndexType} from a {@link BsonValue} in situations when there is no builder method
+ * that better satisfies your needs.
+ * This method cannot be used to validate the syntax.
+ *
+ * Example
+ * The following code creates two functionally equivalent {@link SearchIndexType}s,
+ * though they may not be {@linkplain Object#equals(Object) equal}.
+ *
{@code
+ * SearchIndexType type1 = SearchIndexType.vectorSearch();
+ * SearchIndexType type2 = SearchIndexType.of(new BsonString("vectorSearch"));
+ * }
+ *
+ * @param indexType A {@link BsonValue} representing the required {@link SearchIndexType}.
+ * @return The requested {@link SearchIndexType}.
+ */
+ static SearchIndexType of(final BsonValue indexType) {
+ notNull("indexType", indexType);
+ return new SearchIndexTypeBson(indexType);
+ }
+
+ /**
+ * Converts this object to {@link BsonValue}.
+ *
+ * @return A {@link BsonValue} representing this {@link SearchIndexType}.
+ */
+ BsonValue toBsonValue();
+}
diff --git a/driver-core/src/main/com/mongodb/client/model/SearchIndexTypeBson.java b/driver-core/src/main/com/mongodb/client/model/SearchIndexTypeBson.java
new file mode 100644
index 00000000000..75e8788e681
--- /dev/null
+++ b/driver-core/src/main/com/mongodb/client/model/SearchIndexTypeBson.java
@@ -0,0 +1,52 @@
+package com.mongodb.client.model;
+
+/*
+ * Copyright 2008-present MongoDB, Inc.
+ *
+ * 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
+ *
+ * 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.
+ */
+
+import org.bson.BsonValue;
+
+import java.util.Objects;
+
+final class SearchIndexTypeBson implements SearchIndexType {
+ private final BsonValue bsonValue;
+
+ SearchIndexTypeBson(final BsonValue bsonValue) {
+ this.bsonValue = bsonValue;
+ }
+
+ @Override
+ public BsonValue toBsonValue() {
+ return bsonValue;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SearchIndexTypeBson that = (SearchIndexTypeBson) o;
+ return Objects.equals(bsonValue, that.bsonValue);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(bsonValue);
+ }
+}
+
diff --git a/driver-core/src/main/com/mongodb/internal/operation/CreateSearchIndexesOperation.java b/driver-core/src/main/com/mongodb/internal/operation/CreateSearchIndexesOperation.java
index 1a44d887586..2e52e3fa0ae 100644
--- a/driver-core/src/main/com/mongodb/internal/operation/CreateSearchIndexesOperation.java
+++ b/driver-core/src/main/com/mongodb/internal/operation/CreateSearchIndexesOperation.java
@@ -17,6 +17,7 @@
package com.mongodb.internal.operation;
import com.mongodb.MongoNamespace;
+import com.mongodb.client.model.SearchIndexType;
import org.bson.BsonArray;
import org.bson.BsonDocument;
import org.bson.BsonString;
@@ -52,6 +53,10 @@ private static BsonDocument convert(final SearchIndexRequest request) {
if (searchIndexName != null) {
bsonIndexRequest.append("name", new BsonString(searchIndexName));
}
+ SearchIndexType searchIndexType = request.getSearchIndexType();
+ if (searchIndexType != null) {
+ bsonIndexRequest.append("type", searchIndexType.toBsonValue());
+ }
bsonIndexRequest.append("definition", request.getDefinition());
return bsonIndexRequest;
}
diff --git a/driver-core/src/main/com/mongodb/internal/operation/Operations.java b/driver-core/src/main/com/mongodb/internal/operation/Operations.java
index e271f23d522..5ec696b61ce 100644
--- a/driver-core/src/main/com/mongodb/internal/operation/Operations.java
+++ b/driver-core/src/main/com/mongodb/internal/operation/Operations.java
@@ -48,6 +48,7 @@
import com.mongodb.client.model.ReplaceOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.model.SearchIndexModel;
+import com.mongodb.client.model.SearchIndexType;
import com.mongodb.client.model.UpdateManyModel;
import com.mongodb.client.model.UpdateOneModel;
import com.mongodb.client.model.UpdateOptions;
@@ -752,7 +753,8 @@ private List toBsonDocumentList(@Nullable final List extends Bso
private SearchIndexRequest createSearchIndexRequest(final SearchIndexModel model) {
BsonDocument definition = assertNotNull(toBsonDocument(model.getDefinition()));
String indexName = model.getName();
+ SearchIndexType searchIndexType = model.getType();
- return new SearchIndexRequest(definition, indexName);
+ return new SearchIndexRequest(definition, indexName, searchIndexType);
}
}
diff --git a/driver-core/src/main/com/mongodb/internal/operation/SearchIndexRequest.java b/driver-core/src/main/com/mongodb/internal/operation/SearchIndexRequest.java
index cf8b1cbfbd9..0d37d2c2178 100644
--- a/driver-core/src/main/com/mongodb/internal/operation/SearchIndexRequest.java
+++ b/driver-core/src/main/com/mongodb/internal/operation/SearchIndexRequest.java
@@ -16,6 +16,7 @@
package com.mongodb.internal.operation;
+import com.mongodb.client.model.SearchIndexType;
import com.mongodb.lang.Nullable;
import org.bson.BsonDocument;
@@ -34,11 +35,18 @@ final class SearchIndexRequest {
private final BsonDocument definition;
@Nullable
private final String indexName;
+ @Nullable
+ private final SearchIndexType searchIndexType;
- SearchIndexRequest(final BsonDocument definition, @Nullable final String indexName) {
+ SearchIndexRequest(final BsonDocument definition, @Nullable final String indexName, @Nullable final SearchIndexType searchIndexType) {
assertNotNull(definition);
this.definition = definition;
this.indexName = indexName;
+ this.searchIndexType = searchIndexType;
+ }
+
+ SearchIndexRequest(final BsonDocument definition, @Nullable final String indexName) {
+ this(definition, indexName, null);
}
public BsonDocument getDefinition() {
@@ -49,4 +57,9 @@ public BsonDocument getDefinition() {
public String getIndexName() {
return indexName;
}
+ @Nullable
+ public SearchIndexType getSearchIndexType() {
+ return searchIndexType;
+ }
+
}
diff --git a/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndex.json b/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndex.json
index f9c4e44d3ee..327cb612593 100644
--- a/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndex.json
+++ b/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndex.json
@@ -50,7 +50,8 @@
"mappings": {
"dynamic": true
}
- }
+ },
+ "type": "search"
}
},
"expectError": {
@@ -73,7 +74,8 @@
"mappings": {
"dynamic": true
}
- }
+ },
+ "type": "search"
}
],
"$db": "database0"
@@ -97,7 +99,8 @@
"dynamic": true
}
},
- "name": "test index"
+ "name": "test index",
+ "type": "search"
}
},
"expectError": {
@@ -121,7 +124,68 @@
"dynamic": true
}
},
- "name": "test index"
+ "name": "test index",
+ "type": "search"
+ }
+ ],
+ "$db": "database0"
+ }
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "description": "create a vector search index",
+ "operations": [
+ {
+ "name": "createSearchIndex",
+ "object": "collection0",
+ "arguments": {
+ "model": {
+ "definition": {
+ "fields": [
+ {
+ "type": "vector",
+ "path": "plot_embedding",
+ "numDimensions": 1536,
+ "similarity": "euclidean"
+ }
+ ]
+ },
+ "name": "test index",
+ "type": "vectorSearch"
+ }
+ },
+ "expectError": {
+ "isError": true,
+ "errorContains": "Atlas"
+ }
+ }
+ ],
+ "expectEvents": [
+ {
+ "client": "client0",
+ "events": [
+ {
+ "commandStartedEvent": {
+ "command": {
+ "createSearchIndexes": "collection0",
+ "indexes": [
+ {
+ "definition": {
+ "fields": [
+ {
+ "type": "vector",
+ "path": "plot_embedding",
+ "numDimensions": 1536,
+ "similarity": "euclidean"
+ }
+ ]
+ },
+ "name": "test index",
+ "type": "vectorSearch"
}
],
"$db": "database0"
diff --git a/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndexes.json b/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndexes.json
index 3cf56ce12e0..d91d7d9cf3c 100644
--- a/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndexes.json
+++ b/driver-core/src/test/resources/unified-test-format/index-management/createSearchIndexes.json
@@ -83,7 +83,8 @@
"mappings": {
"dynamic": true
}
- }
+ },
+ "type": "search"
}
]
},
@@ -107,7 +108,8 @@
"mappings": {
"dynamic": true
}
- }
+ },
+ "type": "search"
}
],
"$db": "database0"
@@ -132,7 +134,8 @@
"dynamic": true
}
},
- "name": "test index"
+ "name": "test index",
+ "type": "search"
}
]
},
@@ -157,7 +160,70 @@
"dynamic": true
}
},
- "name": "test index"
+ "name": "test index",
+ "type": "search"
+ }
+ ],
+ "$db": "database0"
+ }
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "description": "create a vector search index",
+ "operations": [
+ {
+ "name": "createSearchIndexes",
+ "object": "collection0",
+ "arguments": {
+ "models": [
+ {
+ "definition": {
+ "fields": [
+ {
+ "type": "vector",
+ "path": "plot_embedding",
+ "numDimensions": 1536,
+ "similarity": "euclidean"
+ }
+ ]
+ },
+ "name": "test index",
+ "type": "vectorSearch"
+ }
+ ]
+ },
+ "expectError": {
+ "isError": true,
+ "errorContains": "Atlas"
+ }
+ }
+ ],
+ "expectEvents": [
+ {
+ "client": "client0",
+ "events": [
+ {
+ "commandStartedEvent": {
+ "command": {
+ "createSearchIndexes": "collection0",
+ "indexes": [
+ {
+ "definition": {
+ "fields": [
+ {
+ "type": "vector",
+ "path": "plot_embedding",
+ "numDimensions": 1536,
+ "similarity": "euclidean"
+ }
+ ]
+ },
+ "name": "test index",
+ "type": "vectorSearch"
}
],
"$db": "database0"
diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/ListSearchIndexesPublisher.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/ListSearchIndexesPublisher.java
index f7d0eb74f6c..0f4c7d798b3 100644
--- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/ListSearchIndexesPublisher.java
+++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/ListSearchIndexesPublisher.java
@@ -34,7 +34,7 @@
*
* @param The type of the result.
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
@Evolving
public interface ListSearchIndexesPublisher extends Publisher {
diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoCollection.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoCollection.java
index 4e17208b342..821c7723a74 100644
--- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoCollection.java
+++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoCollection.java
@@ -1465,7 +1465,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
* @param indexName the name of the search index to create.
* @param definition Atlas Search index mapping definition.
* @return a {@link Publisher} with search index name.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/createSearchIndexes/ Create Search indexes
* @since 4.11
*/
@@ -1476,7 +1476,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
*
* @param definition Atlas Search index mapping definition.
* @return a {@link Publisher} with search index name.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/createSearchIndexes/ Create Search indexes
* @since 4.11
*/
@@ -1490,7 +1490,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
*
* @param searchIndexModels the search index models.
* @return a {@link Publisher} with the search index names in the order specified by the given list {@link SearchIndexModel}s.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/createSearchIndexes/ Create Search indexes
* @since 4.11
*/
@@ -1501,7 +1501,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
* @param indexName the name of the search index to update.
* @param definition Atlas Search index mapping definition.
* @return an empty publisher that indicates when the operation has completed.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/updateSearchIndex/ Update Search index
* @since 4.11
*/
@@ -1511,7 +1511,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
*
* @param indexName the name of the search index to drop.
* @return an empty publisher that indicates when the operation has completed.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/dropSearchIndex/ Drop Search index
* @since 4.11
*/
@@ -1522,7 +1522,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
*
* @return the fluent list search indexes interface.
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
ListSearchIndexesPublisher listSearchIndexes();
@@ -1533,7 +1533,7 @@ Publisher findOneAndUpdate(ClientSession clientSession, Bson filter,
* @param the target document type of the iterable.
* @return the fluent list search indexes interface.
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
ListSearchIndexesPublisher listSearchIndexes(Class resultClass);
diff --git a/driver-scala/src/main/scala/org/mongodb/scala/ListSearchIndexesObservable.scala b/driver-scala/src/main/scala/org/mongodb/scala/ListSearchIndexesObservable.scala
index 3987e830732..126d5976776 100644
--- a/driver-scala/src/main/scala/org/mongodb/scala/ListSearchIndexesObservable.scala
+++ b/driver-scala/src/main/scala/org/mongodb/scala/ListSearchIndexesObservable.scala
@@ -41,7 +41,7 @@ case class ListSearchIndexesObservable[TResult](wrapped: ListSearchIndexesPublis
* Sets an Atlas Search index name for this operation.
*
* @param indexName Atlas Search index name.
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
*/
def name(indexName: String): ListSearchIndexesObservable[TResult] = {
wrapped.name(indexName)
diff --git a/driver-scala/src/main/scala/org/mongodb/scala/MongoCollection.scala b/driver-scala/src/main/scala/org/mongodb/scala/MongoCollection.scala
index bdd63f9245a..48e09aa7921 100644
--- a/driver-scala/src/main/scala/org/mongodb/scala/MongoCollection.scala
+++ b/driver-scala/src/main/scala/org/mongodb/scala/MongoCollection.scala
@@ -1414,7 +1414,7 @@ case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResul
* @param definition the search index mapping definition.
* @return an Observable with the search index name.
* @since 4.11
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
* @see [[https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/ Create Search Indexes]]
*/
def createSearchIndex(indexName: String, definition: Bson): SingleObservable[String] =
@@ -1426,7 +1426,7 @@ case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResul
* @param definition the search index mapping definition.
* @return an Observable with search index name.
* @since 4.11
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
* @see [[https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/ Create Search Indexes]]
*/
def createSearchIndex(definition: Bson): SingleObservable[String] = wrapped.createSearchIndex(definition)
@@ -1441,7 +1441,7 @@ case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResul
* @return an Observable with the names of the search indexes
* in the order specified by the given list of [[org.mongodb.scala.model.SearchIndexModel]]s.
* @since 4.11
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
* @see [[https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/ Create Search Indexes]]
*/
def createSearchIndexes(searchIndexModels: List[SearchIndexModel]): Observable[String] =
@@ -1454,7 +1454,7 @@ case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResul
* @param definition the search index mapping definition.
* @return an Observable that indicates when the operation has completed.
* @since 4.11
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
* @see [[https://www.mongodb.com/docs/manual/reference/command/updateSearchIndex/ Update Search Index]]
*/
def updateSearchIndex(indexName: String, definition: Bson): SingleObservable[Unit] =
@@ -1466,7 +1466,7 @@ case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResul
* @param indexName the name of the search index to drop.
* @return an Observable that indicates when the operation has completed.
* @since 4.11
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
* @see [[https://www.mongodb.com/docs/manual/reference/command/dropSearchIndex/ Drop Search Index]]
*/
def dropSearchIndex(indexName: String): SingleObservable[Unit] = wrapped.dropSearchIndex(indexName)
@@ -1477,7 +1477,7 @@ case class MongoCollection[TResult](private val wrapped: JMongoCollection[TResul
* @tparam C the target document type of the observable.
* @return the fluent list search indexes interface
* @since 4.11
- * @note Requires MongoDB 7.0 or greater
+ * @note Requires MongoDB 6.0 or greater
* @see [[https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSearchIndexes List Search Indexes]]
*/
def listSearchIndexes[C]()(implicit e: C DefaultsTo Document, ct: ClassTag[C]): ListSearchIndexesObservable[C] =
diff --git a/driver-scala/src/main/scala/org/mongodb/scala/model/package.scala b/driver-scala/src/main/scala/org/mongodb/scala/model/package.scala
index 111af0e6568..0d23a38c2e8 100644
--- a/driver-scala/src/main/scala/org/mongodb/scala/model/package.scala
+++ b/driver-scala/src/main/scala/org/mongodb/scala/model/package.scala
@@ -19,7 +19,7 @@ package org.mongodb.scala
import com.mongodb.annotations.{ Beta, Reason, Sealed }
import scala.collection.JavaConverters._
-import com.mongodb.client.model.{ GeoNearOptions, MongoTimeUnit => JMongoTimeUnit, WindowOutputField }
+import com.mongodb.client.model.{ MongoTimeUnit => JMongoTimeUnit }
import org.mongodb.scala.bson.conversions.Bson
// scalastyle:off number.of.methods number.of.types
@@ -481,6 +481,11 @@ package object model {
*/
type SearchIndexModel = com.mongodb.client.model.SearchIndexModel
+ /**
+ * Represents an Atlas Search Index type, which is utilized for creating specific types of indexes.
+ */
+ type SearchIndexType = com.mongodb.client.model.SearchIndexType
+
/**
* A model describing the creation of a single Atlas Search index.
*/
@@ -507,6 +512,17 @@ package object model {
*/
def apply(indexName: String, definition: Bson): SearchIndexModel =
new com.mongodb.client.model.SearchIndexModel(indexName, definition)
+
+ /**
+ * Construct an instance with the given search index name and definition.
+ *
+ * @param indexName the name of the search index to create.
+ * @param definition the search index mapping definition.
+ * @param indexType the search index type.
+ * @return the SearchIndexModel
+ */
+ def apply(indexName: Option[String], definition: Bson, indexType: Option[SearchIndexType]): SearchIndexModel =
+ new com.mongodb.client.model.SearchIndexModel(indexName.orNull, definition, indexType.orNull)
}
/**
diff --git a/driver-sync/src/main/com/mongodb/client/ListSearchIndexesIterable.java b/driver-sync/src/main/com/mongodb/client/ListSearchIndexesIterable.java
index 2384fcef29d..a5579bacfd5 100644
--- a/driver-sync/src/main/com/mongodb/client/ListSearchIndexesIterable.java
+++ b/driver-sync/src/main/com/mongodb/client/ListSearchIndexesIterable.java
@@ -34,7 +34,7 @@
* @param The type of the result.
* @mongodb.driver.manual reference/operator/aggregation/listSearchIndexes ListSearchIndexes
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
@Evolving
public interface ListSearchIndexesIterable extends MongoIterable {
diff --git a/driver-sync/src/main/com/mongodb/client/MongoCollection.java b/driver-sync/src/main/com/mongodb/client/MongoCollection.java
index 7db38040bed..0d3248b613f 100644
--- a/driver-sync/src/main/com/mongodb/client/MongoCollection.java
+++ b/driver-sync/src/main/com/mongodb/client/MongoCollection.java
@@ -1751,7 +1751,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
* @param indexName the name of the search index to create.
* @param definition the search index mapping definition.
* @return the search index name.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/createSearchIndexes/ Create Search indexes
* @since 4.11
*/
@@ -1762,7 +1762,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
*
* @param definition the search index mapping definition.
* @return the search index name.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/createSearchIndexes/ Create Search indexes
* @since 4.11
*/
@@ -1776,7 +1776,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
*
* @param searchIndexModels the search index models.
* @return the search index names in the order specified by the given list of {@link SearchIndexModel}s.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/createSearchIndexes/ Create Search indexes
* @since 4.11
*/
@@ -1787,7 +1787,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
*
* @param indexName the name of the search index to update.
* @param definition the search index mapping definition.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/updateSearchIndex/ Update Search index
* @since 4.11
*/
@@ -1797,7 +1797,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
* Drop an Atlas Search index given its name.
*
* @param indexName the name of the search index to drop.
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
* @mongodb.driver.manual reference/command/dropSearchIndex/ Drop Search index
* @since 4.11
*/
@@ -1808,7 +1808,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
*
* @return the list search indexes iterable interface.
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
ListSearchIndexesIterable listSearchIndexes();
@@ -1819,7 +1819,7 @@ BulkWriteResult bulkWrite(ClientSession clientSession, List extends WriteModel
* @param the target document type of the iterable.
* @return the list search indexes iterable interface.
* @since 4.11
- * @mongodb.server.release 7.0
+ * @mongodb.server.release 6.0
*/
ListSearchIndexesIterable listSearchIndexes(Class resultClass);
diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractAtlasSearchIndexManagementProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractAtlasSearchIndexManagementProseTest.java
index fd7bc428576..17c007e14ba 100644
--- a/driver-sync/src/test/functional/com/mongodb/client/AbstractAtlasSearchIndexManagementProseTest.java
+++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractAtlasSearchIndexManagementProseTest.java
@@ -17,9 +17,11 @@
package com.mongodb.client;
import com.mongodb.MongoClientSettings;
+import com.mongodb.MongoCommandException;
import com.mongodb.ReadConcern;
import com.mongodb.WriteConcern;
import com.mongodb.client.model.SearchIndexModel;
+import com.mongodb.client.model.SearchIndexType;
import com.mongodb.event.CommandListener;
import com.mongodb.event.CommandStartedEvent;
import org.bson.BsonDocument;
@@ -32,7 +34,6 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -46,11 +47,15 @@
import static com.mongodb.assertions.Assertions.assertFalse;
import static com.mongodb.client.Fixture.getMongoClientSettings;
import static com.mongodb.client.Fixture.getMongoClientSettingsBuilder;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
/**
- * See Search Index Management Tests
+ * See Search Index Management Tests
*/
public abstract class AbstractAtlasSearchIndexManagementProseTest {
/**
@@ -74,6 +79,18 @@ public abstract class AbstractAtlasSearchIndexManagementProseTest {
"{"
+ " mappings: { dynamic: true }"
+ "}");
+ private static final Document VECTOR_SEARCH_DEFINITION = Document.parse(
+ "{"
+ + " fields: ["
+ + " {"
+ + " type: 'vector',"
+ + " path: 'plot_embedding',"
+ + " numDimensions: 1536,"
+ + " similarity: 'euclidean',"
+ + " },"
+ + " ]"
+ + "}");
+
private MongoClient client = createMongoClient(getMongoClientSettings());
private MongoDatabase db;
private MongoCollection collection;
@@ -153,7 +170,7 @@ public void shouldCreateMultipleIndexesInBatch() throws InterruptedException {
SearchIndexModel searchIndexModel2 = new SearchIndexModel(TEST_SEARCH_INDEX_NAME_2, NOT_DYNAMIC_MAPPING_DEFINITION);
//when
- List searchIndexes = collection.createSearchIndexes(Arrays.asList(searchIndexModel1, searchIndexModel2));
+ List searchIndexes = collection.createSearchIndexes(asList(searchIndexModel1, searchIndexModel2));
//then
assertThat(searchIndexes, contains(TEST_SEARCH_INDEX_NAME_1, TEST_SEARCH_INDEX_NAME_2));
@@ -200,6 +217,69 @@ public void shouldSuppressNamespaceErrorWhenDroppingIndexWithoutCollection() {
collection.dropSearchIndex("not existent index");
}
+ @Test
+ @DisplayName("Case 7 implicit: Driver can successfully handle search index types when creating indexes")
+ public void shouldHandleImplicitSearchIndexTypes() throws InterruptedException {
+ //given
+ String indexName = "test-search-index-case7-implicit";
+
+ //when
+ String result = collection.createSearchIndex(
+ indexName,
+ NOT_DYNAMIC_MAPPING_DEFINITION);
+
+ //then
+ assertEquals(indexName, result);
+ awaitIndexChanges(isQueryable().and(hasSearchIndexType()), new SearchIndexModel(indexName, NOT_DYNAMIC_MAPPING_DEFINITION));
+ }
+
+ @Test
+ @DisplayName("Case 7 explicit 'search' type: Driver can successfully handle search index types when creating indexes")
+ public void shouldHandleExplicitSearchIndexTypes() throws InterruptedException {
+ //given
+ String indexName = "test-search-index-case7-explicit";
+
+ //when
+ List searchIndexes = collection.createSearchIndexes(singletonList(new SearchIndexModel(
+ indexName,
+ NOT_DYNAMIC_MAPPING_DEFINITION,
+ SearchIndexType.search())));
+
+ //then
+ assertEquals(1, searchIndexes.size());
+ assertEquals(indexName, searchIndexes.get(0));
+ awaitIndexChanges(isQueryable().and(hasSearchIndexType()), new SearchIndexModel(indexName, NOT_DYNAMIC_MAPPING_DEFINITION));
+ }
+
+ @Test
+ @DisplayName("Case 7 explicit 'vectorSearch' type: Driver can successfully handle search index types when creating indexes")
+ public void shouldHandleExplicitVectorSearchIndexTypes() throws InterruptedException {
+ //given
+ String indexName = "test-search-index-case7-vector";
+
+ //when
+ List searchIndexes = collection.createSearchIndexes(singletonList(new SearchIndexModel(
+ indexName,
+ VECTOR_SEARCH_DEFINITION,
+ SearchIndexType.vectorSearch())));
+
+ //then
+ assertEquals(1, searchIndexes.size());
+ assertEquals(indexName, searchIndexes.get(0));
+ awaitIndexChanges(isQueryable().and(hasVectorSearchIndexType()), new SearchIndexModel(indexName, NOT_DYNAMIC_MAPPING_DEFINITION));
+ }
+
+ @Test
+ @DisplayName("Case 8: Driver requires explicit type to create a vector search index")
+ public void shouldRequireExplicitTypeToCreateVectorSearchIndex() {
+ //given
+ String indexName = "test-search-index-case8-error";
+
+ //when & then
+ assertThrows(MongoCommandException.class, () -> collection.createSearchIndex(
+ indexName,
+ VECTOR_SEARCH_DEFINITION));
+ }
private void assertIndexDeleted() throws InterruptedException {
int attempts = MAX_WAIT_ATTEMPTS;
@@ -250,6 +330,16 @@ private Predicate isReady() {
}
+ private Predicate hasSearchIndexType() {
+ return document -> "search".equals(document.getString("type"));
+ }
+
+ private Predicate hasVectorSearchIndexType() {
+ return document -> "vectorSearch".equals(document.getString("type"));
+ }
+
+
+
private boolean checkAttempt(final int attempt) {
Assertions.assertFalse(attempt <= 0, "Exceeded maximum attempts waiting for Search Index changes in Atlas cluster");
return true;
diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudHelper.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudHelper.java
index 67f95903997..041f016510f 100644
--- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudHelper.java
+++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudHelper.java
@@ -68,6 +68,7 @@
import com.mongodb.client.model.ReplaceOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.model.SearchIndexModel;
+import com.mongodb.client.model.SearchIndexType;
import com.mongodb.client.model.TimeSeriesGranularity;
import com.mongodb.client.model.TimeSeriesOptions;
import com.mongodb.client.model.UpdateManyModel;
@@ -99,6 +100,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -1508,19 +1510,24 @@ OperationResult executeCreateSearchIndex(final BsonDocument operation) {
MongoCollection collection = getMongoCollection(operation);
BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
BsonDocument model = arguments.getDocument("model");
- BsonDocument definition = model.getDocument("definition");
return resultOf(() -> {
- if (model.containsKey("name")) {
- String name = model.getString("name").getValue();
- collection.createSearchIndex(name, definition);
- } else {
- collection.createSearchIndex(definition);
- }
+ collection.createSearchIndexes(Collections.singletonList(toIndexSearchModel(model)));
return null;
});
}
+ private static SearchIndexType getSearchIndexType(final BsonString type) {
+ switch (type.getValue()) {
+ case "search":
+ return SearchIndexType.search();
+ case "vectorSearch":
+ return SearchIndexType.vectorSearch();
+ default:
+ throw new UnsupportedOperationException("Unsupported search index type: " + type.getValue());
+ }
+ }
+
OperationResult executeCreateSearchIndexes(final BsonDocument operation) {
MongoCollection collection = getMongoCollection(operation);
BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
@@ -1561,14 +1568,12 @@ OperationResult executeDropSearchIndex(final BsonDocument operation) {
private static SearchIndexModel toIndexSearchModel(final BsonValue bsonValue) {
BsonDocument model = bsonValue.asDocument();
- String name;
BsonDocument definition = model.getDocument("definition");
- if (model.containsKey("name")) {
- name = model.getString("name").getValue();
- return new SearchIndexModel(name, definition);
- } else {
- return new SearchIndexModel(definition);
- }
+ SearchIndexType type = model.containsKey("type") ? getSearchIndexType(model.getString("type")) : null;
+ String name = Optional.ofNullable(model.getString("name", null))
+ .map(BsonString::getValue).
+ orElse(null);
+ return new SearchIndexModel(name, definition, type);
}