You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.0 KiB
100 lines
3.0 KiB
'use strict';
|
|
|
|
const get = require('../get');
|
|
const utils = require('../../utils');
|
|
|
|
/**
|
|
* Given a Mongoose index definition (key + options objects) and a MongoDB server
|
|
* index definition, determine if the two indexes are equal.
|
|
*
|
|
* @param {Object} key the Mongoose index spec
|
|
* @param {Object} options the Mongoose index definition's options
|
|
* @param {Object} dbIndex the index in MongoDB as returned by `listIndexes()`
|
|
* @api private
|
|
*/
|
|
|
|
module.exports = function isIndexEqual(key, options, dbIndex) {
|
|
// Special case: text indexes have a special format in the db. For example,
|
|
// `{ name: 'text' }` becomes:
|
|
// {
|
|
// v: 2,
|
|
// key: { _fts: 'text', _ftsx: 1 },
|
|
// name: 'name_text',
|
|
// ns: 'test.tests',
|
|
// background: true,
|
|
// weights: { name: 1 },
|
|
// default_language: 'english',
|
|
// language_override: 'language',
|
|
// textIndexVersion: 3
|
|
// }
|
|
if (dbIndex.textIndexVersion != null) {
|
|
// 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(weightsAndKeys)) {
|
|
if (!(prop in key)) {
|
|
return false;
|
|
}
|
|
const weight = weightsAndKeys[prop];
|
|
if (weight !== get(options, 'weights.' + prop) && !(weight === 1 && get(options, 'weights.' + prop) == null)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (options['default_language'] !== dbIndex['default_language']) {
|
|
return dbIndex['default_language'] === 'english' && options['default_language'] == null;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const optionKeys = [
|
|
'unique',
|
|
'partialFilterExpression',
|
|
'sparse',
|
|
'expireAfterSeconds',
|
|
'collation'
|
|
];
|
|
for (const key of optionKeys) {
|
|
if (!(key in options) && !(key in dbIndex)) {
|
|
continue;
|
|
}
|
|
if (key === 'collation') {
|
|
if (options[key] == null || dbIndex[key] == null) {
|
|
return options[key] == null && dbIndex[key] == null;
|
|
}
|
|
const definedKeys = Object.keys(options.collation);
|
|
const schemaCollation = options.collation;
|
|
const dbCollation = dbIndex.collation;
|
|
for (const opt of definedKeys) {
|
|
if (get(schemaCollation, opt) !== get(dbCollation, opt)) {
|
|
return false;
|
|
}
|
|
}
|
|
} else if (!utils.deepEqual(options[key], dbIndex[key])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
const schemaIndexKeys = Object.keys(key);
|
|
const dbIndexKeys = Object.keys(dbIndex.key);
|
|
if (schemaIndexKeys.length !== dbIndexKeys.length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < schemaIndexKeys.length; ++i) {
|
|
if (schemaIndexKeys[i] !== dbIndexKeys[i]) {
|
|
return false;
|
|
}
|
|
if (!utils.deepEqual(key[schemaIndexKeys[i]], dbIndex.key[dbIndexKeys[i]])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|