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.
138 lines
3.7 KiB
138 lines
3.7 KiB
'use strict';
|
|
|
|
const Aspect = require('./operation').Aspect;
|
|
const defineAspects = require('./operation').defineAspects;
|
|
const CommandOperationV2 = require('./command_v2');
|
|
const MongoError = require('../core').MongoError;
|
|
const parseIndexOptions = require('../utils').parseIndexOptions;
|
|
const maxWireVersion = require('../core/utils').maxWireVersion;
|
|
|
|
const VALID_INDEX_OPTIONS = new Set([
|
|
'background',
|
|
'unique',
|
|
'name',
|
|
'partialFilterExpression',
|
|
'sparse',
|
|
'expireAfterSeconds',
|
|
'storageEngine',
|
|
'collation',
|
|
|
|
// text indexes
|
|
'weights',
|
|
'default_language',
|
|
'language_override',
|
|
'textIndexVersion',
|
|
|
|
// 2d-sphere indexes
|
|
'2dsphereIndexVersion',
|
|
|
|
// 2d indexes
|
|
'bits',
|
|
'min',
|
|
'max',
|
|
|
|
// geoHaystack Indexes
|
|
'bucketSize',
|
|
|
|
// wildcard indexes
|
|
'wildcardProjection'
|
|
]);
|
|
|
|
class CreateIndexesOperation extends CommandOperationV2 {
|
|
/**
|
|
* @ignore
|
|
*/
|
|
constructor(parent, collection, indexes, options) {
|
|
super(parent, options);
|
|
this.collection = collection;
|
|
|
|
// createIndex can be called with a variety of styles:
|
|
// coll.createIndex('a');
|
|
// coll.createIndex({ a: 1 });
|
|
// coll.createIndex([['a', 1]]);
|
|
// createIndexes is always called with an array of index spec objects
|
|
if (!Array.isArray(indexes) || Array.isArray(indexes[0])) {
|
|
this.onlyReturnNameOfCreatedIndex = true;
|
|
// TODO: remove in v4 (breaking change); make createIndex return full response as createIndexes does
|
|
|
|
const indexParameters = parseIndexOptions(indexes);
|
|
// Generate the index name
|
|
const name = typeof options.name === 'string' ? options.name : indexParameters.name;
|
|
// Set up the index
|
|
const indexSpec = { name, key: indexParameters.fieldHash };
|
|
// merge valid index options into the index spec
|
|
for (let optionName in options) {
|
|
if (VALID_INDEX_OPTIONS.has(optionName)) {
|
|
indexSpec[optionName] = options[optionName];
|
|
}
|
|
}
|
|
this.indexes = [indexSpec];
|
|
return;
|
|
}
|
|
|
|
this.indexes = indexes;
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
execute(server, callback) {
|
|
const options = this.options;
|
|
const indexes = this.indexes;
|
|
|
|
const serverWireVersion = maxWireVersion(server);
|
|
|
|
// Ensure we generate the correct name if the parameter is not set
|
|
for (let i = 0; i < indexes.length; i++) {
|
|
// Did the user pass in a collation, check if our write server supports it
|
|
if (indexes[i].collation && serverWireVersion < 5) {
|
|
callback(
|
|
new MongoError(
|
|
`Server ${server.name}, which reports wire version ${serverWireVersion}, does not support collation`
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (indexes[i].name == null) {
|
|
const keys = [];
|
|
|
|
for (let name in indexes[i].key) {
|
|
keys.push(`${name}_${indexes[i].key[name]}`);
|
|
}
|
|
|
|
// Set the name
|
|
indexes[i].name = keys.join('_');
|
|
}
|
|
}
|
|
|
|
const cmd = { createIndexes: this.collection, indexes };
|
|
|
|
if (options.commitQuorum != null) {
|
|
if (serverWireVersion < 9) {
|
|
callback(
|
|
new MongoError('`commitQuorum` option for `createIndexes` not supported on servers < 4.4')
|
|
);
|
|
return;
|
|
}
|
|
cmd.commitQuorum = options.commitQuorum;
|
|
}
|
|
|
|
// collation is set on each index, it should not be defined at the root
|
|
this.options.collation = undefined;
|
|
|
|
super.executeCommand(server, cmd, (err, result) => {
|
|
if (err) {
|
|
callback(err);
|
|
return;
|
|
}
|
|
|
|
callback(null, this.onlyReturnNameOfCreatedIndex ? indexes[0].name : result);
|
|
});
|
|
}
|
|
}
|
|
|
|
defineAspects(CreateIndexesOperation, [Aspect.WRITE_OPERATION, Aspect.EXECUTE_WITH_SELECTION]);
|
|
|
|
module.exports = CreateIndexesOperation;
|