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]);
 | |
|     }
 | |
|   }
 | |
| };
 |