123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- 'use strict';
- const get = require('../get');
- const utils = require('../../utils');
- /*!
- * 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 collectIndexes = function(schema, prefix) {
- // 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);
- const length = keys.length;
- for (let i = 0; i < length; ++i) {
- const key = keys[i];
- const path = schema.paths[key];
- if (path.$isMongooseDocumentArray || path.$isSingleNested) {
- if (get(path, 'options.excludeIndexes') !== true &&
- get(path, 'schemaOptions.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]._originalSchema,
- prefix + key + '.');
- }
- }
- // 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 = utils.isObject(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 {
- field[prefix + key] = 1;
- }
- delete options.type;
- if (!('background' in options)) {
- options.background = true;
- }
- indexes.push([field, options]);
- }
- }
- 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);
- }
- };
- collectIndexes(schema);
- return 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 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];
- }
- indexes.push([newindex, subindexes[i][1]]);
- }
- }
- };
|