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