@@ -1273,10 +1273,14 @@ for (const i in EventEmitter.prototype) {
12731273}
12741274
12751275/**
1276- * This function is responsible for building [indexes](https://www.mongodb.com/docs/manual/indexes/),
1277- * unless [`autoIndex`](https://mongoosejs.com/docs/guide.html#autoIndex) is turned off.
1276+ * This function is responsible for initializing the underlying connection in MongoDB based on schema options.
1277+ * This function performs the following operations:
12781278 *
1279- * Mongoose calls this function automatically when a model is created using
1279+ * - `createCollection()` unless [`autoCreate`](https://mongoosejs.com/docs/guide.html#autoCreate) option is turned off
1280+ * - `ensureIndexes()` unless [`autoIndex`](https://mongoosejs.com/docs/guide.html#autoIndex) option is turned off
1281+ * - `createSearchIndex()` on all schema search indexes if `autoSearchIndex` is enabled.
1282+ *
1283+ * Mongoose calls this function automatically when a model is a created using
12801284 * [`mongoose.model()`](https://mongoosejs.com/docs/api/mongoose.html#Mongoose.prototype.model()) or
12811285 * [`connection.model()`](https://mongoosejs.com/docs/api/connection.html#Connection.prototype.model()), so you
12821286 * don't need to call `init()` to trigger index builds.
@@ -1324,6 +1328,23 @@ Model.init = function init() {
13241328 }
13251329 return await this . ensureIndexes ( { _automatic : true } ) ;
13261330 } ;
1331+ const _createSearchIndexes = async ( ) => {
1332+ const autoSearchIndex = utils . getOption (
1333+ 'autoSearchIndex' ,
1334+ this . schema . options ,
1335+ conn . config ,
1336+ conn . base . options
1337+ ) ;
1338+ if ( ! autoSearchIndex ) {
1339+ return ;
1340+ }
1341+
1342+ const results = [ ] ;
1343+ for ( const searchIndex of this . schema . _searchIndexes ) {
1344+ results . push ( await this . createSearchIndex ( searchIndex ) ) ;
1345+ }
1346+ return results ;
1347+ } ;
13271348 const _createCollection = async ( ) => {
13281349 if ( ( conn . readyState === STATES . connecting || conn . readyState === STATES . disconnected ) && conn . _shouldBufferCommands ( ) ) {
13291350 await new Promise ( resolve => {
@@ -1342,7 +1363,9 @@ Model.init = function init() {
13421363 return await this . createCollection ( ) ;
13431364 } ;
13441365
1345- this . $init = _createCollection ( ) . then ( ( ) => _ensureIndexes ( ) ) ;
1366+ this . $init = _createCollection ( ) .
1367+ then ( ( ) => _ensureIndexes ( ) ) .
1368+ then ( ( ) => _createSearchIndexes ( ) ) ;
13461369
13471370 const _catch = this . $init . catch ;
13481371 const _this = this ;
@@ -1506,6 +1529,72 @@ Model.syncIndexes = async function syncIndexes(options) {
15061529 return dropped ;
15071530} ;
15081531
1532+ /**
1533+ * Create an [Atlas search index](https://www.mongodb.com/docs/atlas/atlas-search/create-index/).
1534+ * This function only works when connected to MongoDB Atlas.
1535+ *
1536+ * #### Example:
1537+ *
1538+ * const schema = new Schema({ name: { type: String, unique: true } });
1539+ * const Customer = mongoose.model('Customer', schema);
1540+ * await Customer.createSearchIndex({ name: 'test', definition: { mappings: { dynamic: true } } });
1541+ *
1542+ * @param {Object } description index options, including `name` and `definition`
1543+ * @param {String } description.name
1544+ * @param {Object } description.definition
1545+ * @return {Promise }
1546+ * @api public
1547+ */
1548+
1549+ Model . createSearchIndex = async function createSearchIndex ( description ) {
1550+ _checkContext ( this , 'createSearchIndex' ) ;
1551+
1552+ return await this . $__collection . createSearchIndex ( description ) ;
1553+ } ;
1554+
1555+ /**
1556+ * Update an existing [Atlas search index](https://www.mongodb.com/docs/atlas/atlas-search/create-index/).
1557+ * This function only works when connected to MongoDB Atlas.
1558+ *
1559+ * #### Example:
1560+ *
1561+ * const schema = new Schema({ name: { type: String, unique: true } });
1562+ * const Customer = mongoose.model('Customer', schema);
1563+ * await Customer.updateSearchIndex('test', { mappings: { dynamic: true } });
1564+ *
1565+ * @param {String } name
1566+ * @param {Object } definition
1567+ * @return {Promise }
1568+ * @api public
1569+ */
1570+
1571+ Model . updateSearchIndex = async function updateSearchIndex ( name , definition ) {
1572+ _checkContext ( this , 'updateSearchIndex' ) ;
1573+
1574+ return await this . $__collection . updateSearchIndex ( name , definition ) ;
1575+ } ;
1576+
1577+ /**
1578+ * Delete an existing [Atlas search index](https://www.mongodb.com/docs/atlas/atlas-search/create-index/) by name.
1579+ * This function only works when connected to MongoDB Atlas.
1580+ *
1581+ * #### Example:
1582+ *
1583+ * const schema = new Schema({ name: { type: String, unique: true } });
1584+ * const Customer = mongoose.model('Customer', schema);
1585+ * await Customer.dropSearchIndex('test');
1586+ *
1587+ * @param {String } name
1588+ * @return {Promise }
1589+ * @api public
1590+ */
1591+
1592+ Model . dropSearchIndex = async function dropSearchIndex ( name ) {
1593+ _checkContext ( this , 'dropSearchIndex' ) ;
1594+
1595+ return await this . $__collection . dropSearchIndex ( name ) ;
1596+ } ;
1597+
15091598/**
15101599 * Does a dry-run of `Model.syncIndexes()`, returning the indexes that `syncIndexes()` would drop and create if you were to run `syncIndexes()`.
15111600 *
0 commit comments