UNPKG

popurelate

Version:

Easily populate and filter documents using data from related collections.

132 lines (131 loc) 4.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mongoOptimizationHelper = void 0; const path_1 = require("../path"); const getFieldsOfPipeline = (pipeline, helper) => { const is = helper.pipelineIs; if (is.query(pipeline)) { return getQueryFields(pipeline.query); } if (is.sort(pipeline)) { return getSortFields(pipeline.sort); } if (is.project(pipeline)) { return getProjectFields(pipeline.project); } if (is.addFields(pipeline)) { return getFieldsOfddFields(pipeline.addFields); } if (is.populate(pipeline)) { return getPopulateFields(pipeline); } if (pipeline.invisible && pipeline.optimizer && pipeline.hints) { return { IAmChangingFields: pipeline.hints.IAmChangingFields || null, IAmDependedOnFields: pipeline.hints.IAmDependedOnFields || new Set(), }; } return { IAmChangingFields: null, IAmDependedOnFields: new Set(), }; }; exports.mongoOptimizationHelper = { getFieldsOfPipeline, }; const getDollarSignFields = (basePath, parentPath, query, fieldSet = new Set()) => { if (typeof query === "string") { if (query.indexOf("$") === 0) { fieldSet.add(path_1.normalizeQueryPath(path_1.joinQueryPath(basePath, query.slice(1)))); } } else if (Array.isArray(query)) { for (const elem of query) { getDollarSignFields(basePath, parentPath, elem, fieldSet); } } else if (typeof query === "object" && !!query && query.constructor === Object) { for (const field in query) { const startsWithDolar = field.indexOf("$") === 0; const normalized = startsWithDolar ? field.slice(1) : field; if (!startsWithDolar) { fieldSet.add(path_1.normalizeQueryPath(path_1.joinQueryPath(basePath, normalized))); } const value = query[field]; const newBasePath = field === "$elemMatch" ? parentPath : basePath; getDollarSignFields(newBasePath, startsWithDolar ? parentPath : path_1.joinQueryPath(parentPath, normalized), value, fieldSet); } } return fieldSet; }; const getQueryFields = (query) => { const dependedFields = getDollarSignFields("", "", query); return { IAmDependedOnFields: dependedFields, IAmChangingFields: null, }; }; const getSortFields = (sort) => getQueryFields(sort); const getProjectFields = (project) => { let hasInclusiveProject = false; const dependedFields = new Set(); for (const field in project) { const value = project[field]; if ((typeof value === "number" && value !== 0) || value === true || typeof value === "string") { hasInclusiveProject = true; } } const projectFields = new Set(); for (const field in project) { const value = project[field]; projectFields.add(path_1.normalizeQueryPath(field)); if (typeof value === "number" && value !== 0) { dependedFields.add(path_1.normalizeQueryPath(field)); } getDollarSignFields("", "", value, dependedFields); } return { IAmDependedOnFields: dependedFields, IAmChangingFields: hasInclusiveProject ? { isChangingEveryField: true, except: projectFields } : { isChangingEveryField: false, fields: projectFields }, }; }; const getFieldsOfddFields = (addFields) => { const changingFields = new Set(); const dependedFields = new Set(); for (const field in addFields) { const value = addFields[field]; changingFields.add(path_1.normalizeQueryPath(field)); getDollarSignFields("", "", value, dependedFields); } return { IAmDependedOnFields: dependedFields, IAmChangingFields: { isChangingEveryField: false, fields: changingFields }, }; }; const getPopulateFields = (populate) => { const changingFields = new Set(); const dependedFields = new Set(); const helper = (pip) => { if (!pip.populate.alreadyPopulated) { changingFields.add(path_1.normalizeQueryPath(path_1.joinQueryPath(pip.populate.globalPathPrefix, pip.field))); dependedFields.add(path_1.normalizeQueryPath(path_1.joinQueryPath(pip.populate.globalPathPrefix, pip.populate.localField))); } if (pip.populate.children) { for (const key in pip.populate.children) { const child = pip.populate.children[key]; helper(child); } } }; helper(populate); return { IAmDependedOnFields: dependedFields, IAmChangingFields: { isChangingEveryField: false, fields: changingFields }, }; };