@@ -1273,10 +1273,14 @@ for (const i in EventEmitter.prototype) {
1273
1273
}
1274
1274
1275
1275
/**
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:
1278
1278
*
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
1280
1284
* [`mongoose.model()`](https://mongoosejs.com/docs/api/mongoose.html#Mongoose.prototype.model()) or
1281
1285
* [`connection.model()`](https://mongoosejs.com/docs/api/connection.html#Connection.prototype.model()), so you
1282
1286
* don't need to call `init()` to trigger index builds.
@@ -1324,6 +1328,23 @@ Model.init = function init() {
1324
1328
}
1325
1329
return await this . ensureIndexes ( { _automatic : true } ) ;
1326
1330
} ;
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
+ } ;
1327
1348
const _createCollection = async ( ) => {
1328
1349
if ( ( conn . readyState === STATES . connecting || conn . readyState === STATES . disconnected ) && conn . _shouldBufferCommands ( ) ) {
1329
1350
await new Promise ( resolve => {
@@ -1342,7 +1363,9 @@ Model.init = function init() {
1342
1363
return await this . createCollection ( ) ;
1343
1364
} ;
1344
1365
1345
- this . $init = _createCollection ( ) . then ( ( ) => _ensureIndexes ( ) ) ;
1366
+ this . $init = _createCollection ( ) .
1367
+ then ( ( ) => _ensureIndexes ( ) ) .
1368
+ then ( ( ) => _createSearchIndexes ( ) ) ;
1346
1369
1347
1370
const _catch = this . $init . catch ;
1348
1371
const _this = this ;
@@ -1506,6 +1529,72 @@ Model.syncIndexes = async function syncIndexes(options) {
1506
1529
return dropped ;
1507
1530
} ;
1508
1531
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
+
1509
1598
/**
1510
1599
* Does a dry-run of `Model.syncIndexes()`, returning the indexes that `syncIndexes()` would drop and create if you were to run `syncIndexes()`.
1511
1600
*
0 commit comments