UNPKG

mongo-pipeliner

Version:

A practical and userful set of tools to help you build and test MongoDB aggregation pipelines.

407 lines (406 loc) 15.3 kB
/// <reference types="mongoose/types/aggregate" /> /// <reference types="mongoose/types/callback" /> /// <reference types="mongoose/types/collection" /> /// <reference types="mongoose/types/connection" /> /// <reference types="mongoose/types/cursor" /> /// <reference types="mongoose/types/document" /> /// <reference types="mongoose/types/error" /> /// <reference types="mongoose/types/expressions" /> /// <reference types="mongoose/types/helpers" /> /// <reference types="mongoose/types/middlewares" /> /// <reference types="mongoose/types/indexes" /> /// <reference types="mongoose/types/models" /> /// <reference types="mongoose/types/mongooseoptions" /> /// <reference types="mongoose/types/pipelinestage" /> /// <reference types="mongoose/types/populate" /> /// <reference types="mongoose/types/query" /> /// <reference types="mongoose/types/schemaoptions" /> /// <reference types="mongoose/types/schematypes" /> /// <reference types="mongoose/types/session" /> /// <reference types="mongoose/types/types" /> /// <reference types="mongoose/types/utility" /> /// <reference types="mongoose/types/validation" /> /// <reference types="mongoose/types/virtuals" /> /// <reference types="mongoose/types/inferschematype" /> import { ICustomLookupStageParams, IDetailedAggregationPipelineBuilder, ILookupStageParams, IMergeStageParams } from './types'; import { Model, PipelineStage } from 'mongoose'; export interface BaseAggregationPipelineBuilder extends AggregationPipelineBuilder { match(match: { [k: string]: any; }): BaseAggregationPipelineBuilder; group(group: { _id: string; [k: string]: any; }): BaseAggregationPipelineBuilder; sort(sort: { [k: string]: 1 | -1; }): BaseAggregationPipelineBuilder; limit(limit: number): BaseAggregationPipelineBuilder; skip(skip: number): BaseAggregationPipelineBuilder; set(payload: { [k: string]: any; }): BaseAggregationPipelineBuilder; unset(prop: string | string[]): BaseAggregationPipelineBuilder; project(projection: { [k: string]: any; }): BaseAggregationPipelineBuilder; count(count: string): BaseAggregationPipelineBuilder; facet(params: { [k: string]: any; }): BaseAggregationPipelineBuilder; out(collectionName: string): BaseAggregationPipelineBuilder; lookup(params: ILookupStageParams): BaseAggregationPipelineBuilder; customLookup(params: ICustomLookupStageParams): BaseAggregationPipelineBuilder; customUnwindLookup(params: ICustomLookupStageParams): BaseAggregationPipelineBuilder; paginate(limit: number, page: number): BaseAggregationPipelineBuilder; addCustom(stage: PipelineStage): BaseAggregationPipelineBuilder; addFields(fields: { [k: string]: any; }): BaseAggregationPipelineBuilder; unwind(path: string, preserveNullAndEmptyArrays: boolean): BaseAggregationPipelineBuilder; merge(params: IMergeStageParams): BaseAggregationPipelineBuilder; unionWith(collectionName: string, pipeline: any[]): BaseAggregationPipelineBuilder; execute(): Promise<any[]>; assemble(reset?: boolean): PipelineStage[]; reset(): void; } /** * A class that helps you build aggregation pipelines. * It can be used in two ways: * * 1. Extending this class and defining your own methods * 2. Using the methods directly and managing the pipeline on your own * * @class * @implements {IDetailedAggregationPipelineBuilder} * * @example * * import { AggregationPipelineBuilder } from '../lib/base/pipeline-builder'; * import mongoose from 'mongoose'; * import { UserSchema } from '../shared/schema'; * * const User = mongoose.model('User', UserSchema); * * class UserPipeliner extends AggregationPipelineBuilder { * listPaginated(filter: any, page: number, limit: number) { * return this.match(filter).paginate(page, limit).execute(); * } * } * */ export declare class AggregationPipelineBuilder<T extends BaseAggregationPipelineBuilder = BaseAggregationPipelineBuilder> implements IDetailedAggregationPipelineBuilder<T> { protected pipeline: PipelineStage[]; protected collection?: Model<any>; constructor(collection?: Model<any>, pipeline?: PipelineStage[]); /** * Filters the documents to pass only * those that match the specified conditions. * * @param match - The query in the $match stage * @returns {} * */ match(match: { [k: string]: any; }): T; /** * Groups documents by some specified key * and can perform various aggregate * operations such as adding, counting, * obtaining averages, etc. * * @param group - The query in the $group stage * @returns {AggregationPipelineBuilder} * */ group(group: { _id: string; [k: string]: any; }): T; /** * Sort documents by one or more fields. * * @param {*} sort - The query in the $sort stage * @returns {AggregationPipelineBuilder} * */ sort(sort: { [k: string]: 1 | -1; }): T; /** * Limits the number of documents passed * to the next stage in the pipeline. * * @param {number} limit - The query in the $limit stage * @returns {AggregationPipelineBuilder} * */ limit(limit: number): T; /** * Skips over a specified number of documents * and passes the remaining documents * to the next stage in the pipeline. * * @param {number} skip - The query in the $skip stage * @returns {AggregationPipelineBuilder} * */ skip(skip: number): T; /** * Adds new fields to documents. * * @param {*} payload - The query in the $set stage * @returns {AggregationPipelineBuilder} * */ set(payload: { [k: string]: any; }): T; /** * Removes/excludes fields from documents. * * @param {string | string[]} prop - The query in the $unset stage * @returns {AggregationPipelineBuilder} * */ unset(prop: string | string[]): T; /** * Reshapes each document in the stream, * such as by adding new fields or removing existing fields. * * @param {*} projection - The query in the $project stage * @returns {AggregationPipelineBuilder} * */ project(projection: { [k: string]: any; }): T; /** * Counts the number of documents input to the stage. * * @param {string} count - The query in the $count stage * @returns {AggregationPipelineBuilder} * */ count(count: string): T; /** * Process a set of input documents in multiple different ways, * all in a single aggregation stage. * * @param params - The query in the $lookup stage * @returns {AggregationPipelineBuilder} * */ facet(params: { [k: string]: any; }): T; /** * Writes the resulting documents of the aggregation pipeline * to a collection. The stage can incorporate the results * into an existing collection or write to a new collection. * * @param {string} collectionName - The query in the $out stage * @returns {AggregationPipelineBuilder} * */ out(collectionName: string): T; /** * Writes the resulting documents of the aggregation pipeline * to a collection. The stage can incorporate the results * into an existing collection or write to a new collection. * * IMPORTANT: * * - If the collection does not exist, the $merge stage creates the collection. * - If the collection does exist, the $merge stage combines the documents from the input * and the specified collection. * * @param {string} into - Into which collection the results will be written * @param {string} on - Optional. Field or fields that act as a unique identifier * for a document. * @param {string} whenMatched - Optional. The behavior of $merge if a result document and * an existing document in the collection have the same value * for the specified on field(s). * @param {string} whenNotMatched - Optional. The behavior of $merge if a result document does * not match an existing document in the out collection. * @returns {AggregationPipelineBuilder} */ merge(params: IMergeStageParams): T; /** * Performs a union of two collections. $unionWith combines pipeline results from two collections * into a single result set. The stage outputs the combined result set (including duplicates) * to the next stage. * * @param {string} collectionName - The name of the collection to union with * @param {any[]} pipeline - The pipeline to execute on the unioned collection * * @returns {AggregationPipelineBuilder} */ unionWith(collectionName: string, pipeline: any[]): T; /** * Perform a join with another collection. * It can be used to combine documents from two collections. * * @param {string} from - Collection to join * @param {string} localField - Field from the input documents * @param {string} foreignField - Field from the documents of the "from" collection * @param {string} as - Name of the new array field to add to the input documents * @returns {AggregationPipelineBuilder} * */ lookup(params: ILookupStageParams): T; /** * Deconstructs an array field from the input documents to output a document * for each element. * Each output document is the input document with the value of the array * field replaced by the element. * * @param {string} path - Path to unwind * @param {boolean} preserveNullAndEmptyArrays - If true, if the path is null or empty, it will be preserved * @returns {AggregationPipelineBuilder} */ unwind(path: string, preserveNullAndEmptyArrays?: boolean): T; /** * Adds new fields to documents. $addFields outputs documents that contain all * existing fields from the input documents and newly added fields. * * @param {object} fields - The fields to add * @returns {AggregationPipelineBuilder} */ addFields(fields: { [k: string]: any; }): T; /** * Perform a join with another collection. * It can be used to combine documents from two collections. * This method allows you to specify a custom pipeline * to execute on the joined collection. * * @param {string} collectionName - Collection to join * @param {string} localField - Field from the input documents * @param {string} matchExpression - Filter condition for the documents of the "from" collection * @param {string} projection - Specifies the fields to return in the documents of the "from" collection * @param {string} as - Name of the new array field to add to the input documents * @returns {AggregationPipelineBuilder} * * @example * * const pipeliner = new AggregationPipelineBuilder(); * const result = pipeliner * .customLookup({ * collectionName: 'bookings', * localField: 'bookingId', * matchExpression: { $eq: ['$_id', '$$bookingId'] }, * projection: { _id: 0, name: 1, date: 1 }, * as: 'bookings', * }) * * // In case you need to implement an alias for 'composed' localField * // Just ensure to use the 'alias' property in the matchExpression object * * const pipeliner = new AggregationPipelineBuilder(); * const result = pipeliner * .customLookup({ * collectionName: 'authors', * localField: { * ref: 'author.refId', * alias: 'authorId', * }, * matchExpression: { $eq: ['$_id', '$$authorId'] }, * projection: { _id: 0, name: 1, date: 1 }, * as: 'author', * }) * */ customLookup(params: ICustomLookupStageParams): T; /** * Perform a join with another collection. * It can be used to combine documents from two collections. * This method allows you to specify a custom pipeline * to execute on the joined collection. * * It also unwind the joined collection automatically. * * * @param {string} collectionName - Collection to join * @param {string} localField - Field from the input documents * @param {string} matchExpression - Filter condition for the documents of the "from" collection * @param {string} projection - Specifies the fields to return in the documents of the "from" collection * @param {string} as - Name of the new array field to add to the input documents * @returns {AggregationPipelineBuilder} * * @example * * const pipeliner = new AggregationPipelineBuilder(); * const result = pipeliner * .customUnwindLookup({ * collectionName: 'bookings', * localField: 'bookingId', * matchExpression: { $eq: ['$_id', '$$bookingId'] }, * projection: { _id: 0, name: 1, date: 1 }, * as: 'bookings', * }) * * // In case you need to implement an alias for 'composed' localField * // Just ensure to use the 'alias' property in the matchExpression object * * const pipeliner = new AggregationPipelineBuilder(); * const result = pipeliner * .customLookup({ * collectionName: 'authors', * localField: { * ref: 'author.refId', * alias: 'authorId', * }, * matchExpression: { $eq: ['$_id', '$$authorId'] }, * projection: { _id: 0, name: 1, date: 1 }, * as: 'author', * }) * */ customUnwindLookup(params: ICustomLookupStageParams): T; /** * Builds a pipeline that will paginate the results * according to a limit and page number (skip). * * @param {number} limit - The query in the $limit stage * @param {number} page - The query in the $skip stage * @returns {AggregationPipelineBuilder} */ paginate(limit?: number, page?: number): T; /** * Allows you to add a custom stage to the pipeline. * * NOTE: This method is not type-safe and should be used with caution. * * @param {PipelineStage} stage - The custom stage to add to the pipeline * @returns {AggregationPipelineBuilder} */ addCustom(stage: PipelineStage): T; /** * Performs aggregation using the specified * aggregation pipeline. * * @param params - The query in the $lookup stage * @returns {Promise<any[]>} * */ execute(): Promise<any[]>; /** * Returns the aggregation pipeline. * If reset is true, the pipeline will be reseted. * Otherwise, it will keep the pipeline. * * @param {boolean} reset - If true, the pipeline will be reseted * @returns {PipelineStage[]} - The aggregation pipeline * */ assemble(reset?: boolean): PipelineStage[]; /** * Resets the aggregation pipeline. * @returns {void} * */ reset(): void; }