From 391ececb508368b24b56ae23688f07fece1a5924 Mon Sep 17 00:00:00 2001 From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com> Date: Wed, 24 Mar 2021 16:27:32 -0400 Subject: [PATCH 1/9] collation not added to text indexes --- lib/model.js | 4 +--- test/model.indexes.test.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/model.js b/lib/model.js index 2b5fbb3b5f2..0b9819b90b3 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1575,7 +1575,6 @@ function _ensureIndexes(model, options, callback) { let indexError; options = options || {}; - const done = function(err) { if (err && !model.$caught) { model.emit('error', err); @@ -1635,7 +1634,6 @@ function _ensureIndexes(model, options, callback) { const indexFields = utils.clone(index[0]); const indexOptions = utils.clone(index[1]); delete indexOptions._autoIndex; - _decorateDiscriminatorIndexOptions(model, indexOptions); if ('safe' in options) { _handleSafe(options); @@ -1654,7 +1652,7 @@ function _ensureIndexes(model, options, callback) { indexOptions.background = options.background; } if (model.schema.options.hasOwnProperty('collation') && - !indexOptions.hasOwnProperty('collation')) { + !indexOptions.hasOwnProperty('collation') && Object.values(indexFields) != 'text') { indexOptions.collation = model.schema.options.collation; } diff --git a/test/model.indexes.test.js b/test/model.indexes.test.js index d6d262bd91c..f47c3806249 100644 --- a/test/model.indexes.test.js +++ b/test/model.indexes.test.js @@ -666,5 +666,24 @@ describe('model', function() { ]); }); }); + it('should prevent collation on text indexes (gh-10044)', function() { + return co(function*() { + yield db.db.collection('User').drop().catch(() => {}); + + const userSchema = new mongoose.Schema({ username: String }, { + collation: { + locale: 'en', + strength: 2 + } + }); + userSchema.index({ username: 'text' }, { unique: true }); + const User = db.model('User', userSchema, 'User'); + + yield User.init(); + const indexes = yield User.listIndexes(); + assert.ok(!indexes[1].collation); + yield User.collection.drop(); + }); + }); }); }); From c4897f9505da52054c6fe6c1281af5cdceed5bda Mon Sep 17 00:00:00 2001 From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com> Date: Wed, 24 Mar 2021 16:40:13 -0400 Subject: [PATCH 2/9] TIL Object.values in not supported on all browsers --- lib/model.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/model.js b/lib/model.js index 0b9819b90b3..5ff590a4e15 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1633,6 +1633,9 @@ function _ensureIndexes(model, options, callback) { const indexFields = utils.clone(index[0]); const indexOptions = utils.clone(index[1]); + const textBlock = Object.keys(indexFields).map(function(key) { + return indexFields[key]; + }); delete indexOptions._autoIndex; _decorateDiscriminatorIndexOptions(model, indexOptions); if ('safe' in options) { @@ -1652,7 +1655,7 @@ function _ensureIndexes(model, options, callback) { indexOptions.background = options.background; } if (model.schema.options.hasOwnProperty('collation') && - !indexOptions.hasOwnProperty('collation') && Object.values(indexFields) != 'text') { + !indexOptions.hasOwnProperty('collation') && textBlock != 'text') { indexOptions.collation = model.schema.options.collation; } From f231d7bb49439716e20b054120ad43182b3d8ca6 Mon Sep 17 00:00:00 2001 From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com> Date: Wed, 24 Mar 2021 16:59:54 -0400 Subject: [PATCH 3/9] should work and is designed to handle multiple text fields --- lib/model.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/model.js b/lib/model.js index 5ff590a4e15..26dd0ea674e 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1633,9 +1633,15 @@ function _ensureIndexes(model, options, callback) { const indexFields = utils.clone(index[0]); const indexOptions = utils.clone(index[1]); - const textBlock = Object.keys(indexFields).map(function(key) { - return indexFields[key]; - }); + const textBlock = () => { + const results = Object.keys(indexFields).map(function(key) { + return indexFields[key]; + }); + if (!results.includes('text')) { + return true; + } + return false; + }; delete indexOptions._autoIndex; _decorateDiscriminatorIndexOptions(model, indexOptions); if ('safe' in options) { @@ -1655,7 +1661,7 @@ function _ensureIndexes(model, options, callback) { indexOptions.background = options.background; } if (model.schema.options.hasOwnProperty('collation') && - !indexOptions.hasOwnProperty('collation') && textBlock != 'text') { + !indexOptions.hasOwnProperty('collation') && textBlock()) { indexOptions.collation = model.schema.options.collation; } From 4e74ea7ba11c8a5119c47123aba0fc950f652587 Mon Sep 17 00:00:00 2001 From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com> Date: Wed, 24 Mar 2021 17:14:26 -0400 Subject: [PATCH 4/9] TIL that includes() is also not supported in all browsers --- lib/model.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/model.js b/lib/model.js index 26dd0ea674e..c3c69a255d6 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1637,10 +1637,10 @@ function _ensureIndexes(model, options, callback) { const results = Object.keys(indexFields).map(function(key) { return indexFields[key]; }); - if (!results.includes('text')) { - return true; + if (results.indexOf('text') !== -1) { + return false; } - return false; + return true; }; delete indexOptions._autoIndex; _decorateDiscriminatorIndexOptions(model, indexOptions); From c9bfb3061ba98232aaf9e665f8749dff3bac7db1 Mon Sep 17 00:00:00 2001 From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com> Date: Thu, 25 Mar 2021 11:26:34 -0400 Subject: [PATCH 5/9] Update model.indexes.test.js --- test/model.indexes.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/model.indexes.test.js b/test/model.indexes.test.js index f47c3806249..a0c339cdbae 100644 --- a/test/model.indexes.test.js +++ b/test/model.indexes.test.js @@ -668,8 +668,6 @@ describe('model', function() { }); it('should prevent collation on text indexes (gh-10044)', function() { return co(function*() { - yield db.db.collection('User').drop().catch(() => {}); - const userSchema = new mongoose.Schema({ username: String }, { collation: { locale: 'en', From d1a9a1e7bdb6fdecd43030d4241c092741be95bb Mon Sep 17 00:00:00 2001 From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com> Date: Mon, 29 Mar 2021 11:07:59 -0400 Subject: [PATCH 6/9] made requested changes --- lib/model.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/model.js b/lib/model.js index c3c69a255d6..c653b694b64 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1633,12 +1633,11 @@ function _ensureIndexes(model, options, callback) { const indexFields = utils.clone(index[0]); const indexOptions = utils.clone(index[1]); - const textBlock = () => { - const results = Object.keys(indexFields).map(function(key) { - return indexFields[key]; - }); - if (results.indexOf('text') !== -1) { - return false; + const noText = () => { + for (const key in indexFields) { + if (indexFields[key] == 'text') { + return false; + } } return true; }; @@ -1661,7 +1660,7 @@ function _ensureIndexes(model, options, callback) { indexOptions.background = options.background; } if (model.schema.options.hasOwnProperty('collation') && - !indexOptions.hasOwnProperty('collation') && textBlock()) { + !indexOptions.hasOwnProperty('collation') && noText()) { indexOptions.collation = model.schema.options.collation; } From f24953c1a7c95c6f7f05309a961943da07572211 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 29 Mar 2021 21:53:05 -0400 Subject: [PATCH 7/9] fix(query): add `writeConcern()` method to avoid writeConcern deprecation warning Fix #10009 --- lib/query.js | 47 ++++++++++++++++++++++++++++++++++++++++++++++ test/query.test.js | 12 ++++++++++++ 2 files changed, 59 insertions(+) diff --git a/lib/query.js b/lib/query.js index 86e2e627a22..8aa1bfeba5e 100644 --- a/lib/query.js +++ b/lib/query.js @@ -1083,6 +1083,53 @@ Query.prototype.session = function session(v) { return this; }; +/** + * Sets the 3 write concern parameters for this query: + * + * - `w`: Sets the specified number of `mongod` servers, or tag set of `mongod` servers, that must acknowledge this write before this write is considered successful. + * - `j`: Boolean, set to `true` to request acknowledgement that this operation has been persisted to MongoDB's on-disk journal. + * - `wtimeout`: If [`w > 1`](/docs/api.html#query_Query-w), the maximum amount of time to wait for this write to propagate through the replica set before this operation fails. The default is `0`, which means no timeout. + * + * This option is only valid for operations that write to the database: + * + * - `deleteOne()` + * - `deleteMany()` + * - `findOneAndDelete()` + * - `findOneAndReplace()` + * - `findOneAndUpdate()` + * - `remove()` + * - `update()` + * - `updateOne()` + * - `updateMany()` + * + * Defaults to the schema's [`writeConcern` option](/docs/guide.html#writeConcern) + * + * ####Example: + * + * // The 'majority' option means the `deleteOne()` promise won't resolve + * // until the `deleteOne()` has propagated to the majority of the replica set + * await mongoose.model('Person'). + * deleteOne({ name: 'Ned Stark' }). + * writeConcern({ w: 'majority' }); + * + * @method writeConcern + * @memberOf Query + * @instance + * @param {Object} writeConcern the write concern value to set + * @see mongodb https://mongodb.github.io/node-mongodb-native/3.1/api/global.html#WriteConcern + * @return {Query} this + * @api public + */ + +Query.prototype.writeConcern = function writeConcern(val) { + if (val == null) { + delete this.options.writeConcern; + return this; + } + this.options.writeConcern = val; + return this; +}; + /** * Sets the specified number of `mongod` servers, or tag set of `mongod` servers, * that must acknowledge this write before this write is considered successful. diff --git a/test/query.test.js b/test/query.test.js index e8cb49c9d17..ae121ad2b6d 100644 --- a/test/query.test.js +++ b/test/query.test.js @@ -3776,4 +3776,16 @@ describe('Query', function() { assert.deepEqual(q._fields, { doesntpopulate: 0, populatescorrectly: 0 }); }); + + it('sets `writeConcern` option correctly (gh-10009)', function() { + const testSchema = new mongoose.Schema({ + name: String + }); + const Test = db.model('Test', testSchema); + + const q = Test.find(); + q.writeConcern({ w: 'majority', wtimeout: 1000 }); + + assert.deepEqual(q.options.writeConcern, { w: 'majority', wtimeout: 1000 }); + }); }); From f3cd3a8898aa063487e04ede21a84e78247a2634 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 31 Mar 2021 12:04:05 -0400 Subject: [PATCH 8/9] chore: use variable instead of function --- lib/model.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/model.js b/lib/model.js index c653b694b64..13cb9832345 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1633,14 +1633,12 @@ function _ensureIndexes(model, options, callback) { const indexFields = utils.clone(index[0]); const indexOptions = utils.clone(index[1]); - const noText = () => { - for (const key in indexFields) { - if (indexFields[key] == 'text') { - return false; - } + let isTextIndex = false; + for (const key of Object.keys(indexFields)) { + if (indexFields[key] === 'text') { + isTextIndex = true; } - return true; - }; + } delete indexOptions._autoIndex; _decorateDiscriminatorIndexOptions(model, indexOptions); if ('safe' in options) { @@ -1660,7 +1658,8 @@ function _ensureIndexes(model, options, callback) { indexOptions.background = options.background; } if (model.schema.options.hasOwnProperty('collation') && - !indexOptions.hasOwnProperty('collation') && noText()) { + !indexOptions.hasOwnProperty('collation') + !isTextIndex) { indexOptions.collation = model.schema.options.collation; } From 9e4a0830107c8815e63ef7b11d8fa200f5ca51a6 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 31 Mar 2021 12:05:46 -0400 Subject: [PATCH 9/9] style: fix lint --- lib/model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/model.js b/lib/model.js index 13cb9832345..d5d66d3aed8 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1658,7 +1658,7 @@ function _ensureIndexes(model, options, callback) { indexOptions.background = options.background; } if (model.schema.options.hasOwnProperty('collation') && - !indexOptions.hasOwnProperty('collation') + !indexOptions.hasOwnProperty('collation') && !isTextIndex) { indexOptions.collation = model.schema.options.collation; }