UNPKG

mongodb-aggregate-builder

Version:
434 lines (433 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AggregateBuilder = void 0; const types_1 = require("./types"); class AggregateBuilder { constructor() { this.aggregate = []; } /** * @param groupBy * @param boundaries * @param defaultValue * @param output */ bucket(groupBy, boundaries, defaultValue, output) { this.aggregate.push({ $bucket: { groupBy, boundaries, default: defaultValue, output } }); return this; } /** * @param groupBy * @param buckets * @param output * @param granularity */ bucketAuto(groupBy, buckets, output = {}, granularity = '') { const bucketData = { groupBy, buckets }; if (output !== null && output !== undefined && Object.keys(output).length > 0) { bucketData['output'] = output; } if (granularity) { bucketData['granularity'] = granularity; } this.aggregate.push({ $bucketAuto: bucketData }); return this; } /** * @param allChangesForCluster * @param fullDocument * @param fullDocumentBeforeChange * @param resumeAfter * @param showExpandedEvents * @param startAfter * @param startAtOperationTime */ changeStream(allChangesForCluster, fullDocument, fullDocumentBeforeChange, resumeAfter, showExpandedEvents, startAfter, startAtOperationTime) { const changeStreamData = {}; // TODO implement this later this.aggregate.push({ $changeStream: changeStreamData }); return this; } /** * @param documentsExpression */ documents(documentsExpression) { this.aggregate.push({ $documents: documentsExpression }); return this; } /** * @param facet */ facet(facet) { this.aggregate.push({ $facet: facet }); return this; } /** * @param densifyData */ densify(densifyData) { this.aggregate.push({ $densify: densifyData }); return this; } /** * @param fillData */ fill(fillData) { this.aggregate.push({ $fill: fillData }); return this; } /** * @param geoExpression */ geoNear(geoExpression) { if (this.aggregate.length > 0) { throw new Error('geoNear must be the first stage in the pipeline'); } this.aggregate.push({ $geoNear: geoExpression }); return this; } /** * @param from * @param startWith * @param connectFromField * @param connectToField * @param as * @param maxDepth * @param depthField * @param restrictSearchWithMatch */ graphLookup(from, startWith, connectFromField, connectToField, as, maxDepth = 0, depthField = '', restrictSearchWithMatch = {}) { const graphLookupData = { from, startWith, connectFromField, connectToField, as, }; if (maxDepth < 0) { throw new Error('Max depth must be greater than 0'); } else if (maxDepth > 0) { graphLookupData['maxDepth'] = maxDepth; } if (depthField) { graphLookupData['depthField'] = depthField; } if (Object.keys(restrictSearchWithMatch).length > 0) { graphLookupData['restrictSearchWithMatch'] = restrictSearchWithMatch; } this.aggregate.push({ $graphLookup: graphLookupData }); return this; } /** * @param from * @param localField * @param foreignField * @param as * @param pipeline */ lookup(from, localField, foreignField, as, pipeline = []) { const lookupData = { from, localField, foreignField, as }; if (pipeline.length > 0) { lookupData['pipeline'] = pipeline; } this.aggregate.push({ $lookup: lookupData }); return this; } /** * @param into * @param on * @param letVariables * @param whenMatched * @param whenNotMatched */ merge(into, on = '', letVariables = null, whenMatched = types_1.WhenMatched.MERGE, whenNotMatched = types_1.WhenNotMatched.INSERT) { const mergeData = { into }; if (on) { mergeData['on'] = on; } if (letVariables) { mergeData['let'] = letVariables; } if (whenMatched) { mergeData['whenMatched'] = whenMatched; } if (whenNotMatched) { mergeData['whenNotMatched'] = whenNotMatched; } this.aggregate.push({ $merge: mergeData }); return this; } /** * @param db * @param collection */ out(db, collection) { this.aggregate.push({ $out: { db, coll: collection } }); return this; } /** * @param size */ sample(size) { if (size < 1) { throw new Error('Size must be greater than 0'); } this.aggregate.push({ $sample: { size } }); return this; } /** * @param output * @param partitionBy * @param sortBy * @param window * @param documents * @param range * @param unit */ setWindowFields(output, partitionBy = '', sortBy = null, window = null, documents = null, range = null, unit = null) { const setWindowFieldsData = { output }; if (partitionBy) { setWindowFieldsData['partitionBy'] = partitionBy; } if (sortBy) { setWindowFieldsData['sortBy'] = sortBy; } if (window) { setWindowFieldsData['window'] = window; } if (documents) { setWindowFieldsData['documents'] = documents; } if (range) { setWindowFieldsData['range'] = range; } if (unit) { setWindowFieldsData['unit'] = unit; } this.aggregate.push({ $setWindowFields: setWindowFieldsData }); return this; } unionWith(coll, pipeline) { this.aggregate.push({ $unionWith: { coll, pipeline } }); return this; } unwind(path, preserveNullAndEmptyArrays = false) { this.aggregate.push({ $unwind: { path, preserveNullAndEmptyArrays } }); return this; } /** * @param fields */ unset(fields) { this.aggregate.push({ $unset: fields }); return this; } project(fields) { this.aggregate.push({ $project: fields }); return this; } addFields(fields) { this.aggregate.push({ $addFields: fields }); return this; } /** * * @param newRoot */ replaceRoot(newRoot) { this.aggregate.push({ $replaceRoot: { newRoot } }); return this; } /** * @param newRoot */ replaceWith(newRoot) { this.aggregate.push({ $replaceWith: newRoot }); return this; } /** * @param query */ match(query) { this.aggregate.push({ $match: query }); return this; } /** * @param fields */ group(fields) { this.aggregate.push({ $group: fields }); return this; } /** * @param fields */ set(fields) { this.aggregate.push({ $set: fields }); return this; } /** * @param skipValue */ skip(skipValue) { this.aggregate.push({ $skip: skipValue }); return this; } /** * @param limit */ limit(limit) { this.aggregate.push({ $limit: limit }); return this; } /** * @param expression */ sortByCount(expression) { this.aggregate.push({ $sortByCount: expression }); return this; } /** * @param sort */ sort(sort) { const sortRules = {}; Object.keys(sort).forEach(key => { if (sort[key] === types_1.SortDirection.TEXT_SCORE) { sortRules[key] = { $meta: types_1.SortDirection.TEXT_SCORE }; } else if (sort[key] === types_1.SortDirection.ASC_TEXT || sort[key] === types_1.SortDirection.ASC) { sortRules[key] = types_1.SortDirection.ASC; } else if (sort[key] === types_1.SortDirection.DESC_TEXT || sort[key] === types_1.SortDirection.DESC) { sortRules[key] = types_1.SortDirection.DESC; } }); this.aggregate.push({ $sort: sortRules }); return this; } /** * @param countName */ count(countName) { this.aggregate.push({ $count: countName }); return this; } /** * Merge several part of aggregation in one * @param aggregate */ mergeAggregation(aggregate) { let mergedRules = []; for (const rule of aggregate) { mergedRules = [...mergedRules, ...rule]; } return mergedRules; } /** * Merge several part of aggregation in one with current state * @param aggregate */ mergeAggregationWithCurrent(aggregate) { for (const rule of aggregate) { this.aggregate = [...this.aggregate, ...rule]; } return this; } /** * Return prepared aggregate */ build() { return this.aggregate; } } exports.AggregateBuilder = AggregateBuilder;