123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- '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;
|