Skip to content

Commit 5dd0a4e

Browse files
authored
Merge pull request #13138 from rdeavila94/gh-13136
Updated the isIndexEqual function to take into account non-text index…
2 parents 9dd82be + c8191da commit 5dd0a4e

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

lib/helpers/indexes/isIndexEqual.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,19 @@ module.exports = function isIndexEqual(key, options, dbIndex) {
2828
// textIndexVersion: 3
2929
// }
3030
if (dbIndex.textIndexVersion != null) {
31-
const weights = dbIndex.weights;
32-
if (Object.keys(weights).length !== Object.keys(key).length) {
31+
// If a compound index involves both text and non-text indexes, we want to extract both (gh-13136)
32+
const weightsAndKeys = Object.assign({}, dbIndex.weights);
33+
Object.keys(dbIndex.key)
34+
.filter(function(key) { return !(key.startsWith('_fts'));})
35+
.forEach(function(key) { weightsAndKeys[key] = dbIndex.key[key];});
36+
if (Object.keys(weightsAndKeys).length !== Object.keys(key).length) {
3337
return false;
3438
}
35-
for (const prop of Object.keys(weights)) {
39+
for (const prop of Object.keys(weightsAndKeys)) {
3640
if (!(prop in key)) {
3741
return false;
3842
}
39-
const weight = weights[prop];
43+
const weight = weightsAndKeys[prop];
4044
if (weight !== get(options, 'weights.' + prop) && !(weight === 1 && get(options, 'weights.' + prop) == null)) {
4145
return false;
4246
}

test/model.indexes.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,72 @@ describe('model', function() {
650650
});
651651
});
652652

653+
it('should not re-create a compound text index that involves non-text indexes, using syncIndexes (gh-13136)', function(done) {
654+
const Test = new Schema({
655+
title: {
656+
type: String
657+
},
658+
description: {
659+
type: String
660+
},
661+
age: {
662+
type: Number
663+
}
664+
}, {
665+
autoIndex: false
666+
});
667+
668+
Test.index({
669+
title: 'text',
670+
description: 'text',
671+
age: 1
672+
});
673+
674+
const TestModel = db.model('Test', Test);
675+
TestModel.syncIndexes().then((results1) => {
676+
assert.deepEqual(results1, []);
677+
// second call to syncIndexes should return an empty array, representing 0 deleted indexes
678+
TestModel.syncIndexes().then((results2) => {
679+
assert.deepEqual(results2, []);
680+
done();
681+
});
682+
});
683+
});
684+
685+
it('should not find a diff when calling diffIndexes after syncIndexes involving a text and non-text compound index (gh-13136)', function(done) {
686+
const Test = new Schema({
687+
title: {
688+
type: String
689+
},
690+
description: {
691+
type: String
692+
},
693+
age: {
694+
type: Number
695+
}
696+
}, {
697+
autoIndex: false
698+
});
699+
700+
Test.index({
701+
title: 'text',
702+
description: 'text',
703+
age: 1
704+
});
705+
706+
const TestModel = db.model('Test', Test);
707+
708+
TestModel.diffIndexes().then((diff) => {
709+
assert.deepEqual(diff, { toCreate: [{ age: 1, title: 'text', description: 'text' }], toDrop: [] });
710+
TestModel.syncIndexes().then(() => {
711+
TestModel.diffIndexes().then((diff2) => {
712+
assert.deepEqual(diff2, { toCreate: [], toDrop: [] });
713+
done();
714+
});
715+
});
716+
});
717+
});
718+
653719
it('cleanIndexes (gh-6676)', function() {
654720
return co(function*() {
655721
let M = db.model('Test', new Schema({

0 commit comments

Comments
 (0)