Skip to content

Commit a60e72d

Browse files
authored
Merge pull request Automattic#14987 from Automattic/vkarpov15/Automatticgh-14868
feat(model): add hideIndexes option to syncIndexes() and cleanIndexes()
2 parents e12301b + ca8b52d commit a60e72d

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

lib/model.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ Model.createCollection = async function createCollection(options) {
12201220
*
12211221
* @param {Object} [options] options to pass to `ensureIndexes()`
12221222
* @param {Boolean} [options.background=null] if specified, overrides each index's `background` property
1223+
* @param {Boolean} [options.hideIndexes=false] set to `true` to hide indexes instead of dropping. Requires MongoDB server 4.4 or higher
12231224
* @return {Promise}
12241225
* @api public
12251226
*/
@@ -1440,8 +1441,10 @@ function getIndexesToDrop(schema, schemaIndexes, dbIndexes) {
14401441
*
14411442
* The returned promise resolves to a list of the dropped indexes' names as an array
14421443
*
1443-
* @param {Function} [callback] optional callback
1444-
* @return {Promise|undefined} Returns `undefined` if callback is specified, returns a promise if no callback.
1444+
* @param {Object} [options]
1445+
* @param {Array<String>} [options.toDrop] if specified, contains a list of index names to drop
1446+
* @param {Boolean} [options.hideIndexes=false] set to `true` to hide indexes instead of dropping. Requires MongoDB server 4.4 or higher
1447+
* @return {Promise<String>} list of dropped or hidden index names
14451448
* @api public
14461449
*/
14471450

@@ -1452,23 +1455,32 @@ Model.cleanIndexes = async function cleanIndexes(options) {
14521455
}
14531456
const model = this;
14541457

1455-
const collection = model.$__collection;
1456-
14571458
if (Array.isArray(options && options.toDrop)) {
1458-
const res = await _dropIndexes(options.toDrop, collection);
1459+
const res = await _dropIndexes(options.toDrop, model, options);
14591460
return res;
14601461
}
14611462

14621463
const res = await model.diffIndexes();
1463-
return await _dropIndexes(res.toDrop, collection);
1464+
return await _dropIndexes(res.toDrop, model, options);
14641465
};
14651466

1466-
async function _dropIndexes(toDrop, collection) {
1467+
async function _dropIndexes(toDrop, model, options) {
14671468
if (toDrop.length === 0) {
14681469
return [];
14691470
}
14701471

1471-
await Promise.all(toDrop.map(indexName => collection.dropIndex(indexName)));
1472+
const collection = model.$__collection;
1473+
if (options && options.hideIndexes) {
1474+
await Promise.all(toDrop.map(indexName => {
1475+
return model.db.db.command({
1476+
collMod: collection.collectionName,
1477+
index: { name: indexName, hidden: true }
1478+
});
1479+
}));
1480+
} else {
1481+
await Promise.all(toDrop.map(indexName => collection.dropIndex(indexName)));
1482+
}
1483+
14721484
return toDrop;
14731485
}
14741486

test/model.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4962,6 +4962,31 @@ describe('Model', function() {
49624962
assert.strictEqual(indexes[1].background, false);
49634963
});
49644964

4965+
it('syncIndexes() supports hideIndexes (gh-14868)', async function() {
4966+
const opts = { autoIndex: false };
4967+
const schema = new Schema({ name: String }, opts);
4968+
schema.index({ name: 1 });
4969+
4970+
let M = db.model('Test', schema);
4971+
await M.syncIndexes({});
4972+
4973+
let indexes = await M.listIndexes();
4974+
assert.deepEqual(indexes[1].key, { name: 1 });
4975+
assert.ok(!indexes[1].hidden);
4976+
4977+
db.deleteModel(/Test/);
4978+
M = db.model('Test', new Schema({ name: String }, opts));
4979+
await M.syncIndexes({ hideIndexes: true });
4980+
indexes = await M.listIndexes();
4981+
assert.deepEqual(indexes[1].key, { name: 1 });
4982+
assert.ok(indexes[1].hidden);
4983+
4984+
await M.syncIndexes({});
4985+
indexes = await M.listIndexes();
4986+
assert.equal(indexes.length, 1);
4987+
assert.deepEqual(indexes[0].key, { _id: 1 });
4988+
});
4989+
49654990
it('should not drop a text index on .syncIndexes() call (gh-10850)', async function() {
49664991
const collation = { collation: { locale: 'simple' } };
49674992
const someSchema = new Schema({

types/indexes.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ declare module 'mongoose' {
5757
type IndexDefinition = Record<string, IndexDirection>;
5858

5959
interface SyncIndexesOptions extends mongodb.CreateIndexesOptions {
60-
continueOnError?: boolean
60+
continueOnError?: boolean;
61+
hideIndexes?: boolean;
6162
}
6263
type ConnectionSyncIndexesResult = Record<string, OneCollectionSyncIndexesResult>;
6364
type OneCollectionSyncIndexesResult = Array<string> & mongodb.MongoServerError;

0 commit comments

Comments
 (0)