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.
		
		
		
		
		
			
		
			
				
					
					
						
							156 lines
						
					
					
						
							4.8 KiB
						
					
					
				
			
		
		
	
	
							156 lines
						
					
					
						
							4.8 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
const get = require('../get');
 | 
						|
const helperIsObject = require('../isObject');
 | 
						|
 | 
						|
/*!
 | 
						|
 * Gather all indexes defined in the schema, including single nested,
 | 
						|
 * document arrays, and embedded discriminators.
 | 
						|
 */
 | 
						|
 | 
						|
module.exports = function getIndexes(schema) {
 | 
						|
  let indexes = [];
 | 
						|
  const schemaStack = new WeakMap();
 | 
						|
  const indexTypes = schema.constructor.indexTypes;
 | 
						|
  const indexByName = new Map();
 | 
						|
 | 
						|
  collectIndexes(schema);
 | 
						|
  return indexes;
 | 
						|
 | 
						|
  function collectIndexes(schema, prefix, baseSchema) {
 | 
						|
    // Ignore infinitely nested schemas, if we've already seen this schema
 | 
						|
    // along this path there must be a cycle
 | 
						|
    if (schemaStack.has(schema)) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    schemaStack.set(schema, true);
 | 
						|
 | 
						|
    prefix = prefix || '';
 | 
						|
    const keys = Object.keys(schema.paths);
 | 
						|
 | 
						|
    for (const key of keys) {
 | 
						|
      const path = schema.paths[key];
 | 
						|
      if (baseSchema != null && baseSchema.paths[key]) {
 | 
						|
        // If looking at an embedded discriminator schema, don't look at paths
 | 
						|
        // that the
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      if (path.$isMongooseDocumentArray || path.$isSingleNested) {
 | 
						|
        if (get(path, 'options.excludeIndexes') !== true &&
 | 
						|
            get(path, 'schemaOptions.excludeIndexes') !== true &&
 | 
						|
            get(path, 'schema.options.excludeIndexes') !== true) {
 | 
						|
          collectIndexes(path.schema, prefix + key + '.');
 | 
						|
        }
 | 
						|
 | 
						|
        if (path.schema.discriminators != null) {
 | 
						|
          const discriminators = path.schema.discriminators;
 | 
						|
          const discriminatorKeys = Object.keys(discriminators);
 | 
						|
          for (const discriminatorKey of discriminatorKeys) {
 | 
						|
            collectIndexes(discriminators[discriminatorKey],
 | 
						|
              prefix + key + '.', path.schema);
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        // Retained to minimize risk of backwards breaking changes due to
 | 
						|
        // gh-6113
 | 
						|
        if (path.$isMongooseDocumentArray) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      const index = path._index || (path.caster && path.caster._index);
 | 
						|
 | 
						|
      if (index !== false && index !== null && index !== undefined) {
 | 
						|
        const field = {};
 | 
						|
        const isObject = helperIsObject(index);
 | 
						|
        const options = isObject ? index : {};
 | 
						|
        const type = typeof index === 'string' ? index :
 | 
						|
          isObject ? index.type :
 | 
						|
            false;
 | 
						|
 | 
						|
        if (type && indexTypes.indexOf(type) !== -1) {
 | 
						|
          field[prefix + key] = type;
 | 
						|
        } else if (options.text) {
 | 
						|
          field[prefix + key] = 'text';
 | 
						|
          delete options.text;
 | 
						|
        } else {
 | 
						|
          const isDescendingIndex = Number(index) === -1;
 | 
						|
          field[prefix + key] = isDescendingIndex ? -1 : 1;
 | 
						|
        }
 | 
						|
 | 
						|
        delete options.type;
 | 
						|
        if (!('background' in options)) {
 | 
						|
          options.background = true;
 | 
						|
        }
 | 
						|
        if (schema.options.autoIndex != null) {
 | 
						|
          options._autoIndex = schema.options.autoIndex;
 | 
						|
        }
 | 
						|
 | 
						|
        const indexName = options && options.name;
 | 
						|
        if (typeof indexName === 'string') {
 | 
						|
          if (indexByName.has(indexName)) {
 | 
						|
            Object.assign(indexByName.get(indexName), field);
 | 
						|
          } else {
 | 
						|
            indexes.push([field, options]);
 | 
						|
            indexByName.set(indexName, field);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          indexes.push([field, options]);
 | 
						|
          indexByName.set(indexName, field);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    schemaStack.delete(schema);
 | 
						|
 | 
						|
    if (prefix) {
 | 
						|
      fixSubIndexPaths(schema, prefix);
 | 
						|
    } else {
 | 
						|
      schema._indexes.forEach(function(index) {
 | 
						|
        if (!('background' in index[1])) {
 | 
						|
          index[1].background = true;
 | 
						|
        }
 | 
						|
      });
 | 
						|
      indexes = indexes.concat(schema._indexes);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /*!
 | 
						|
   * Checks for indexes added to subdocs using Schema.index().
 | 
						|
   * These indexes need their paths prefixed properly.
 | 
						|
   *
 | 
						|
   * schema._indexes = [ [indexObj, options], [indexObj, options] ..]
 | 
						|
   */
 | 
						|
 | 
						|
  function fixSubIndexPaths(schema, prefix) {
 | 
						|
    const subindexes = schema._indexes;
 | 
						|
    const len = subindexes.length;
 | 
						|
    for (let i = 0; i < len; ++i) {
 | 
						|
      const indexObj = subindexes[i][0];
 | 
						|
      const indexOptions = subindexes[i][1];
 | 
						|
      const keys = Object.keys(indexObj);
 | 
						|
      const klen = keys.length;
 | 
						|
      const newindex = {};
 | 
						|
 | 
						|
      // use forward iteration, order matters
 | 
						|
      for (let j = 0; j < klen; ++j) {
 | 
						|
        const key = keys[j];
 | 
						|
        newindex[prefix + key] = indexObj[key];
 | 
						|
      }
 | 
						|
 | 
						|
      const newIndexOptions = Object.assign({}, indexOptions);
 | 
						|
      if (indexOptions != null && indexOptions.partialFilterExpression != null) {
 | 
						|
        newIndexOptions.partialFilterExpression = {};
 | 
						|
        const partialFilterExpression = indexOptions.partialFilterExpression;
 | 
						|
        for (const key of Object.keys(partialFilterExpression)) {
 | 
						|
          newIndexOptions.partialFilterExpression[prefix + key] =
 | 
						|
            partialFilterExpression[key];
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      indexes.push([newindex, newIndexOptions]);
 | 
						|
    }
 | 
						|
  }
 | 
						|
};
 |