diff --git a/.github/workflows/check_schema_version.sh b/.github/workflows/check_schema_version.sh index ebd1e64a84..67dccd03b7 100755 --- a/.github/workflows/check_schema_version.sh +++ b/.github/workflows/check_schema_version.sh @@ -5,11 +5,7 @@ exitCode=0 # $1 - takes a single argument of the path to the JSON file containing a schemaVersion key at the top level. function get_schema_version() { - node << EOF - const { readFileSync } = require('fs') - const { load } = require('js-yaml') - console.log(load(readFileSync("./$1", { encoding: 'utf-8' })).schemaVersion) -EOF + js-yaml $1 | jq -r .schemaVersion } function get_all_schemaVersion_defining_files () { diff --git a/.github/workflows/unified-test-format-schema-check.yml b/.github/workflows/unified-test-format-schema-check.yml index bf5e99fdbb..282cc5f3bf 100644 --- a/.github/workflows/unified-test-format-schema-check.yml +++ b/.github/workflows/unified-test-format-schema-check.yml @@ -22,8 +22,7 @@ jobs: node-version: lts/* - name: Install dependencies run: | - npm install -g ajv-cli - npm install js-yaml + npm install -g ajv-cli js-yaml - name: Check unified format test files against schema working-directory: source/unified-test-format/tests run: make diff --git a/source/client-side-encryption/client-side-encryption.rst b/source/client-side-encryption/client-side-encryption.rst index ad361126a3..71fddb9848 100644 --- a/source/client-side-encryption/client-side-encryption.rst +++ b/source/client-side-encryption/client-side-encryption.rst @@ -2118,9 +2118,11 @@ endSessions BYPASS startSession BYPASS create BYPASS createIndexes BYPASS +createSearchIndexes BYPASS drop BYPASS dropDatabase BYPASS dropIndexes BYPASS +dropSearchIndex BYPASS killCursors BYPASS listCollections BYPASS listDatabases BYPASS @@ -2132,6 +2134,7 @@ killAllSessions BYPASS killSessions BYPASS killAllSessionsByPattern BYPASS refreshSessions BYPASS +updateSearchIndex BYPASS ======================== =========== All AUTOENCRYPT commands are sent to mongocryptd, even if there is no diff --git a/source/index-management/index-management.rst b/source/index-management/index-management.rst index dec5d628a6..1f601a1866 100644 --- a/source/index-management/index-management.rst +++ b/source/index-management/index-management.rst @@ -852,6 +852,188 @@ Example:: > a [ "_id_", "ty_1", "l_2dsphere", "ts_1" ] +-------------- +Search Indexes +-------------- + +Server 7.0 introduced three new server commands and a new aggregation stage to facilitate management of search indexes. Drivers MUST provide +an API similar to the existing index management API specifically for search indexes. Drivers MAY choose to implement either the standard +API or the index view API. + +Search Index Management Helper Options +-------------------------------------- + +There are currently no supported options for any of the search index management commands. To future proof +drivers implementations so that any options added in the future do not constitute a breaking change to drivers, +empty options structs have been added as placeholders. If a driver's language has a mechanism to add options +in a non-breaking manner (i.e., method overloading) drivers MAY omit the empty options structs from their +search index management helpers. + +``listSearchIndexes`` is implemented using an aggregation pipeline. The list helper MUST support a driver's aggregation +options as outline in the `CRUD specification `_. Drivers MAY combine the aggregation options with +any future ``listSearchIndexes`` stage options, if that is idiomatic for a driver's language. + +Notes +----- + +The search index commands are asynchronous and return from the server before the index is successfully updated, created or dropped. +In order to determine when an index has been created / updated, users are expected to run the ``listSearchIndexes`` repeatedly +until index changes appear. + +An example, from Javascript: + +.. code:: typescript + + const name = await collection.createSearchIndex({ definition: { ... fill out definition } }) + while (!(await collection.listSearchIndexes({ name }).hasNext())) { + await setTimeout(1000); + } + +Common Interfaces +----------------- + +.. code:: typescript + + interface SearchIndexModel { + // The definition for this index. + definition: Document; + + // The name for this index, if present. + name: Optional; + } + + /** + * The following interfaces are empty but are provided as placeholders for drivers that cannot + * add options in a non-breaking manner, if options are added in the future. + */ + interface CreateSearchIndexOptions {} + interface UpdateSearchIndexOptions {} + interface ListSearchIndexOptions {} + interface DropSearchIndexOptions {} + +Standard API for Search Indexes +------------------------------- + +.. code:: typescript + + interface Collection { + /** + * Convenience method for creating a single search index. + * + * @return The name of the created search index + * + * @note Drivers MAY opt to implement this method signature, the signature that + * takes an SearchIndexModel as a parameter, or for those languages with method + * overloading MAY decide to implement both. + */ + createSearchIndex(name: String, definition: Document, options: Optional): String; + + /** + * Convenience method for creating a single index. + * + * @return The name of the created search index + * + * @note Drivers MAY opt to implement this method signature, the signature that + * takes an name and a definition as parameters, or for those languages with method + * overloading MAY decide to implement both. + */ + createSearchIndex(model: SearchIndexModel, options: Optional): String; + + /** + * Creates multiple search indexes on the collection. + * + * @return An iterable of the newly created index names. + */ + createSearchIndexes(models: Iterable, options: CreateSearchIndexOptions): Iterable; + + /** + * Updates the search index with the given name to use the provided + * definition. + */ + updateSearchIndex(name: String, definition: Document, options: Optional): void; + + /** + * Drops the search index with the given name. + */ + dropSearchIndex(name: String, options: Optional): void; + + /** + * Gets index information for one or more search indexes in the collection. + * + * If name is not specified, information for all indexes on the specified collection will be returned. + */ + listSearchIndexes(name: Optional, aggregationOptions: Optional, listIndexOptions: Optional): Cursor; + } + +Index View API for Search Indexes +--------------------------------- + +.. code:: typescript + + interface Collection { + /** + * Returns the search index view for this collection. + */ + searchIndexes(name: Optional, aggregateOptions: Optional, options: Optional): SearchIndexView; + } + + interface SearchIndexView extends Iterable { + /** + * Enumerates the index information for all search indexes in the collection. + * + * @note For drivers that cannot make the IndexView iterable, they MUST implement a list + * method. See below. + */ + iterator(): Iterator; + + /** + * For drivers that cannot make SearchIndexView iterable, they MUST implement this method to + * return a list of indexes. In the case of async drivers, this MAY return a Future + * or language/implementation equivalent. + */ + list(): Cursor; + + + /** + * This is a convenience method for creating a single index. + * + * @return The name of the created index. + * + * @note Drivers MAY opt to implement this method signature, the signature that + * takes an SearchIndexModel as a parameter, or for those languages with method + * overloading MAY decide to implement both. + */ + createOne(name: String, definition: Document, options: Optional): String; + + /** + * This is a convenience method for creating a single index. + * + * @return The name of the created index. + * + * @note Drivers MAY opt to implement this method signature, the signature that + * takes an name and a definition as parameters, or for those languages with method + * overloading MAY decide to implement both. + */ + createOne(model: SearchIndexModel, options: Optional): String; + + /** + * Creates multiple search indexes in the collection. + * + * @return The names of the created indexes. + */ + createMany(models: Iterable, options: Optional): Iterable; + + /** + * Drops a single search index from the collection by the index name. + */ + dropOne(name: String, options: Optional): Result; + + /** + * Updates a single search index from the collection by the index name. + */ + updateOne(name: String, options: Optional): Result; + } + --------- Q & A --------- @@ -908,5 +1090,6 @@ Changelog :2022-04-18: Added the ``clustered`` attribute to ``IndexOptions`` in order to support clustered collections. :2022-10-05: Remove spec front matter and reformat changelog. -:2023-5-10: Merge index enumeration and index management specs and get rid of references +:2023-05-10: Merge index enumeration and index management specs and get rid of references to legacy server versions. +:2023-05-18: Add the search index management API. diff --git a/source/index-management/tests/createSearchIndex.json b/source/index-management/tests/createSearchIndex.json new file mode 100644 index 0000000000..da664631e7 --- /dev/null +++ b/source/index-management/tests/createSearchIndex.json @@ -0,0 +1,134 @@ +{ + "description": "createSearchIndex", + "schemaVersion": "1.4", + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "database0" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "collection0" + } + } + ], + "runOnRequirements": [ + { + "minServerVersion": "7.0.0", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + } + ], + "tests": [ + { + "description": "no name provided for an index definition", + "operations": [ + { + "name": "createSearchIndex", + "object": "collection0", + "arguments": { + "model": { + "definition": { + "mappings": { + "dynamic": true + } + } + } + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "createSearchIndexes": "collection0", + "indexes": [ + { + "definition": { + "mappings": { + "dynamic": true + } + } + } + ], + "$db": "database0" + } + } + } + ] + } + ] + }, + { + "description": "name provided for an index definition", + "operations": [ + { + "name": "createSearchIndex", + "object": "collection0", + "arguments": { + "model": { + "definition": { + "mappings": { + "dynamic": true + } + }, + "name": "test index" + } + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "createSearchIndexes": "collection0", + "indexes": [ + { + "definition": { + "mappings": { + "dynamic": true + } + }, + "name": "test index" + } + ], + "$db": "database0" + } + } + } + ] + } + ] + } + ] +} diff --git a/source/index-management/tests/createSearchIndex.yml b/source/index-management/tests/createSearchIndex.yml new file mode 100644 index 0000000000..0eb5c1ab1d --- /dev/null +++ b/source/index-management/tests/createSearchIndex.yml @@ -0,0 +1,60 @@ +description: "createSearchIndex" +schemaVersion: "1.4" +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - database: + id: &database0 database0 + client: *client0 + databaseName: *database0 + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: *collection0 + +runOnRequirements: + - minServerVersion: "7.0.0" + topologies: [ replicaset, load-balanced, sharded ] + serverless: forbid + +tests: + - description: "no name provided for an index definition" + operations: + - name: createSearchIndex + object: *collection0 + arguments: + model: { definition: &definition { mappings: { dynamic: true } } } + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + createSearchIndexes: *collection0 + indexes: [ { definition: *definition } ] + $db: *database0 + + - description: "name provided for an index definition" + operations: + - name: createSearchIndex + object: *collection0 + arguments: + model: { definition: &definition { mappings: { dynamic: true } } , name: 'test index' } + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + createSearchIndexes: *collection0 + indexes: [ { definition: *definition, name: 'test index' } ] + $db: *database0 \ No newline at end of file diff --git a/source/index-management/tests/createSearchIndexes.json b/source/index-management/tests/createSearchIndexes.json new file mode 100644 index 0000000000..b78b3ea6c8 --- /dev/null +++ b/source/index-management/tests/createSearchIndexes.json @@ -0,0 +1,169 @@ +{ + "description": "createSearchIndexes", + "schemaVersion": "1.4", + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "database0" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "collection0" + } + } + ], + "runOnRequirements": [ + { + "minServerVersion": "7.0.0", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + } + ], + "tests": [ + { + "description": "empty index definition array", + "operations": [ + { + "name": "createSearchIndexes", + "object": "collection0", + "arguments": { + "models": [] + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "createSearchIndexes": "collection0", + "indexes": [], + "$db": "database0" + } + } + } + ] + } + ] + }, + { + "description": "no name provided for an index definition", + "operations": [ + { + "name": "createSearchIndexes", + "object": "collection0", + "arguments": { + "models": [ + { + "definition": { + "mappings": { + "dynamic": true + } + } + } + ] + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "createSearchIndexes": "collection0", + "indexes": [ + { + "definition": { + "mappings": { + "dynamic": true + } + } + } + ], + "$db": "database0" + } + } + } + ] + } + ] + }, + { + "description": "name provided for an index definition", + "operations": [ + { + "name": "createSearchIndexes", + "object": "collection0", + "arguments": { + "models": [ + { + "definition": { + "mappings": { + "dynamic": true + } + }, + "name": "test index" + } + ] + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "createSearchIndexes": "collection0", + "indexes": [ + { + "definition": { + "mappings": { + "dynamic": true + } + }, + "name": "test index" + } + ], + "$db": "database0" + } + } + } + ] + } + ] + } + ] +} diff --git a/source/index-management/tests/createSearchIndexes.yml b/source/index-management/tests/createSearchIndexes.yml new file mode 100644 index 0000000000..dc01c1b166 --- /dev/null +++ b/source/index-management/tests/createSearchIndexes.yml @@ -0,0 +1,80 @@ +description: "createSearchIndexes" +schemaVersion: "1.4" +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - database: + id: &database0 database0 + client: *client0 + databaseName: *database0 + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: *collection0 + +runOnRequirements: + - minServerVersion: "7.0.0" + topologies: [ replicaset, load-balanced, sharded ] + serverless: forbid + +tests: + - description: "empty index definition array" + operations: + - name: createSearchIndexes + object: *collection0 + arguments: + models: [] + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + createSearchIndexes: *collection0 + indexes: [] + $db: *database0 + + + - description: "no name provided for an index definition" + operations: + - name: createSearchIndexes + object: *collection0 + arguments: + models: [ { definition: &definition { mappings: { dynamic: true } } } ] + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + createSearchIndexes: *collection0 + indexes: [ { definition: *definition } ] + $db: *database0 + + - description: "name provided for an index definition" + operations: + - name: createSearchIndexes + object: *collection0 + arguments: + models: [ { definition: &definition { mappings: { dynamic: true } } , name: 'test index' } ] + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + createSearchIndexes: *collection0 + indexes: [ { definition: *definition, name: 'test index' } ] + $db: *database0 \ No newline at end of file diff --git a/source/index-management/tests/dropSearchIndex.json b/source/index-management/tests/dropSearchIndex.json new file mode 100644 index 0000000000..b73447f602 --- /dev/null +++ b/source/index-management/tests/dropSearchIndex.json @@ -0,0 +1,73 @@ +{ + "description": "dropSearchIndex", + "schemaVersion": "1.4", + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "database0" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "collection0" + } + } + ], + "runOnRequirements": [ + { + "minServerVersion": "7.0.0", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + } + ], + "tests": [ + { + "description": "sends the correct command", + "operations": [ + { + "name": "dropSearchIndex", + "object": "collection0", + "arguments": { + "name": "test index" + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "dropSearchIndex": "collection0", + "name": "test index", + "$db": "database0" + } + } + } + ] + } + ] + } + ] +} diff --git a/source/index-management/tests/dropSearchIndex.yml b/source/index-management/tests/dropSearchIndex.yml new file mode 100644 index 0000000000..5ffef7d17e --- /dev/null +++ b/source/index-management/tests/dropSearchIndex.yml @@ -0,0 +1,42 @@ +description: "dropSearchIndex" +schemaVersion: "1.4" +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - database: + id: &database0 database0 + client: *client0 + databaseName: *database0 + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: *collection0 + +runOnRequirements: + - minServerVersion: "7.0.0" + topologies: [ replicaset, load-balanced, sharded ] + serverless: forbid + +tests: + - description: "sends the correct command" + operations: + - name: dropSearchIndex + object: *collection0 + arguments: + name: &indexName 'test index' + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + dropSearchIndex: *collection0 + name: *indexName + $db: *database0 + diff --git a/source/index-management/tests/listSearchIndexes.json b/source/index-management/tests/listSearchIndexes.json new file mode 100644 index 0000000000..41e2655fb3 --- /dev/null +++ b/source/index-management/tests/listSearchIndexes.json @@ -0,0 +1,153 @@ +{ + "description": "listSearchIndexes", + "schemaVersion": "1.4", + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "database0" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "collection0" + } + } + ], + "runOnRequirements": [ + { + "minServerVersion": "7.0.0", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + } + ], + "tests": [ + { + "description": "when no name is provided, it does not populate the filter", + "operations": [ + { + "name": "listSearchIndexes", + "object": "collection0", + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "collection0", + "pipeline": [ + { + "$listSearchIndexes": {} + } + ] + } + } + } + ] + } + ] + }, + { + "description": "when a name is provided, it is present in the filter", + "operations": [ + { + "name": "listSearchIndexes", + "object": "collection0", + "arguments": { + "name": "test index" + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "collection0", + "pipeline": [ + { + "$listSearchIndexes": { + "name": "test index" + } + } + ], + "$db": "database0" + } + } + } + ] + } + ] + }, + { + "description": "aggregation cursor options are supported", + "operations": [ + { + "name": "listSearchIndexes", + "object": "collection0", + "arguments": { + "name": "test index", + "aggregationOptions": { + "batchSize": 10 + } + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "collection0", + "cursor": { + "batchSize": 10 + }, + "pipeline": [ + { + "$listSearchIndexes": { + "name": "test index" + } + } + ], + "$db": "database0" + } + } + } + ] + } + ] + } + ] +} diff --git a/source/index-management/tests/listSearchIndexes.yml b/source/index-management/tests/listSearchIndexes.yml new file mode 100644 index 0000000000..7d3c3187b9 --- /dev/null +++ b/source/index-management/tests/listSearchIndexes.yml @@ -0,0 +1,82 @@ +description: "listSearchIndexes" +schemaVersion: "1.4" +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - database: + id: &database0 database0 + client: *client0 + databaseName: *database0 + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: *collection0 + +runOnRequirements: + - minServerVersion: "7.0.0" + topologies: [ replicaset, load-balanced, sharded ] + serverless: forbid + +tests: + - description: "when no name is provided, it does not populate the filter" + operations: + - name: listSearchIndexes + object: *collection0 + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0 + pipeline: + - $listSearchIndexes: {} + + - description: "when a name is provided, it is present in the filter" + operations: + - name: listSearchIndexes + object: *collection0 + arguments: + name: &indexName "test index" + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0 + pipeline: + - $listSearchIndexes: { name: *indexName } + $db: *database0 + + - description: aggregation cursor options are supported + operations: + - name: listSearchIndexes + object: *collection0 + arguments: + name: &indexName "test index" + aggregationOptions: + batchSize: 10 + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0 + cursor: { batchSize: 10 } + pipeline: + - $listSearchIndexes: { name: *indexName } + $db: *database0 \ No newline at end of file diff --git a/source/index-management/tests/updateSearchIndex.json b/source/index-management/tests/updateSearchIndex.json new file mode 100644 index 0000000000..00cd7e7541 --- /dev/null +++ b/source/index-management/tests/updateSearchIndex.json @@ -0,0 +1,75 @@ +{ + "description": "updateSearchIndex", + "schemaVersion": "1.4", + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "database0" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "collection0" + } + } + ], + "runOnRequirements": [ + { + "minServerVersion": "7.0.0", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + } + ], + "tests": [ + { + "description": "sends the correct command", + "operations": [ + { + "name": "updateSearchIndex", + "object": "collection0", + "arguments": { + "name": "test index", + "definition": {} + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "updateSearchIndex": "collection0", + "name": "test index", + "definition": {}, + "$db": "database0" + } + } + } + ] + } + ] + } + ] +} diff --git a/source/index-management/tests/updateSearchIndex.yml b/source/index-management/tests/updateSearchIndex.yml new file mode 100644 index 0000000000..215dbc42f9 --- /dev/null +++ b/source/index-management/tests/updateSearchIndex.yml @@ -0,0 +1,44 @@ +description: "updateSearchIndex" +schemaVersion: "1.4" +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - database: + id: &database0 database0 + client: *client0 + databaseName: *database0 + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: *collection0 + +runOnRequirements: + - minServerVersion: "7.0.0" + topologies: [ replicaset, load-balanced, sharded ] + serverless: forbid + +tests: + - description: "sends the correct command" + operations: + - name: updateSearchIndex + object: *collection0 + arguments: + name: &indexName 'test index' + definition: &definition {} + expectError: + # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing + # against an Atlas cluster and the expectError will be removed. + isError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + updateSearchIndex: *collection0 + name: *indexName + definition: *definition + $db: *database0 + diff --git a/source/unified-test-format/unified-test-format.rst b/source/unified-test-format/unified-test-format.rst index 56a386493b..1367740c1f 100644 --- a/source/unified-test-format/unified-test-format.rst +++ b/source/unified-test-format/unified-test-format.rst @@ -1803,8 +1803,7 @@ specifications: - `Change Streams <../change-streams/change-streams.rst>`__ - `CRUD <../crud/crud.rst>`__ -- `Enumerating Indexes <../enumerate-indexes.rst>`__ -- `Index Management <../index-management.rst>`__ +- `Index Management <../index-management/index-management.rst>`__ Collection operations that require special handling or are not documented by an existing specification are described below. @@ -1916,6 +1915,25 @@ Test runners MUST NOT iterate the resulting cursor when executing this operation and test files SHOULD NOT specify `operation.expectResult `_ for this operation. +createSearchIndex +~~~~~~~~~~~~~~~~~ + +This operations proxies the collection's ``createSearchIndex`` helper with the same arguments. + +Each ``createSearchIndex`` operation receives a `SearchIndexModel `. +If a driver has chosen to implement the ``createSearchIndex(name: String, definition: Document)`` overload +of ``createSearchIndex``, then the ``SearchIndexModel`` should be parsed by ``createSearchIndex`` unified +test runner helper and the correct arguments should be passed into the driver's helper. + +createSearchIndexes +~~~~~~~~~~~~~~~~~~~ + +This operations proxies the collection's ``createSearchIndexes`` helper with the same arguments. + +dropSearchIndex +~~~~~~~~~~~~~~~ + +This operation proxies the collection's ``dropSearchIndex`` helper with the same arguments. find ~~~~ @@ -1962,6 +1980,18 @@ examples:: insertedId: { $$unsetOrMatches: 2 } +listSearchIndexes +~~~~~~~~~~~~~~~~~ + +This operation proxies the collection's ``listSearchIndexes`` helper and returns the result +of the cursor as a list. + +updateSearchIndex +~~~~~~~~~~~~~~~~~ + +This operation proxies the collection's ``updateSearchIndex`` helper with the same arguments. + + watch ~~~~~