From e2ebc754052ef32b12b6c8cbc55268e2dad98975 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 13 Dec 2024 11:20:10 -0500 Subject: [PATCH 1/2] fix(schema): throw error if duplicate index definition using `unique` in schema path and subsequent `.index()` call Fix #15056 --- lib/schema.js | 6 ++++++ test/schema.test.js | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/schema.js b/lib/schema.js index 7caaac75920..26ea5d94818 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -2134,6 +2134,12 @@ Schema.prototype.index = function(fields, options) { } } + for (const existingIndex of this.indexes()) { + if (util.isDeepStrictEqual(existingIndex[0], fields)) { + throw new MongooseError(`Schema already has an index on ${JSON.stringify(fields)}`); + } + } + this._indexes.push([fields, options]); return this; }; diff --git a/test/schema.test.js b/test/schema.test.js index 3076c9df62a..58f761e0219 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -3278,4 +3278,21 @@ describe('schema', function() { assert.ok(subdoc instanceof mongoose.Document); assert.equal(subdoc.getAnswer(), 42); }); + it('throws "already has an index" error if duplicate index definition (gh-15056)', function() { + const ObjectKeySchema = new mongoose.Schema({ + key: { + type: String, + required: true, + unique: true, + }, + type: { + type: String, + required: false, + }, + }); + + assert.throws(() => { + ObjectKeySchema.index({ key: 1 }); + }, /MongooseError.*already has an index/); + }); }); From f70e844c07ca1e56fcebb219bbc2eeab18975d27 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 16 Dec 2024 11:04:45 -0500 Subject: [PATCH 2/2] style: fix lint --- test/schema.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/schema.test.js b/test/schema.test.js index 58f761e0219..6378ec340ac 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -3283,12 +3283,12 @@ describe('schema', function() { key: { type: String, required: true, - unique: true, + unique: true }, type: { type: String, - required: false, - }, + required: false + } }); assert.throws(() => {