Skip to content

Commit

Permalink
Updated the isIndexEqual function to take into account non-text index…
Browse files Browse the repository at this point in the history
…es when checking compound indexes that include both text and non-text indexes
  • Loading branch information
rdeavila94 committed Mar 6, 2023
1 parent e76c41c commit 77b9d99
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 4 deletions.
12 changes: 8 additions & 4 deletions lib/helpers/indexes/isIndexEqual.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ module.exports = function isIndexEqual(key, options, dbIndex) {
// textIndexVersion: 3
// }
if (dbIndex.textIndexVersion != null) {
const weights = dbIndex.weights;
if (Object.keys(weights).length !== Object.keys(key).length) {
// If a compound index involves both text and non-text indexes, we want to extract both (gh-13136)
const weightsAndKeys = Object.assign({}, dbIndex.weights);
Object.keys(dbIndex.key)
.filter(function(key) { return !(key.startsWith('_fts'));})
.forEach(function(key) { weightsAndKeys[key] = dbIndex.key[key];});
if (Object.keys(weightsAndKeys).length !== Object.keys(key).length) {
return false;
}
for (const prop of Object.keys(weights)) {
for (const prop of Object.keys(weightsAndKeys)) {
if (!(prop in key)) {
return false;
}
const weight = weights[prop];
const weight = weightsAndKeys[prop];
if (weight !== get(options, 'weights.' + prop) && !(weight === 1 && get(options, 'weights.' + prop) == null)) {
return false;
}
Expand Down
66 changes: 66 additions & 0 deletions test/model.indexes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,72 @@ describe('model', function() {
});
});

it('should not re-create a compound text index that involves non-text indexes, using syncIndexes (gh-13136)', function(done) {
const Test = new Schema({
title: {
type: String
},
description: {
type: String
},
age: {
type: Number
}
}, {
autoIndex: false
});

Test.index({
title: 'text',
description: 'text',
age: 1
});

const TestModel = db.model('Test', Test);
TestModel.syncIndexes().then((results1) => {
assert.strictEqual(results1, []);
// second call to syncIndexes should return an empty array, representing 0 deleted indexes
TestModel.syncIndexes().then((results2) => {
assert.strictEqual(results2, []);
done();
});
});
});

it('should not find a diff when calling diffIndexes after syncIndexes involving a text and non-text compound index (gh-13136)', function(done) {
const Test = new Schema({
title: {
type: String
},
description: {
type: String
},
age: {
type: Number
}
}, {
autoIndex: false
});

Test.index({
title: 'text',
description: 'text',
age: 1
});

const TestModel = db.model('Test', Test);

TestModel.diffIndexes().then((diff) => {
assert.deepEqual(diff, { toCreate: [{ age: 1, title: 'text', description: 'text' }], toDrop: [] });
TestModel.syncIndexes().then(() => {
TestModel.diffIndexes().then((diff2) => {
assert.deepEqual(diff2, { toCreate: [], toDrop: [] });
done();
});
});
});
});

it('cleanIndexes (gh-6676)', function() {
return co(function*() {
let M = db.model('Test', new Schema({
Expand Down

0 comments on commit 77b9d99

Please sign in to comment.