UNPKG

mongo-bolt

Version:

A lightweight, beginner-friendly MongoDB wrapper with inbuilt caching and simplified joins/indexing.

1,773 lines (1,256 loc) 58.9 kB
# Mongo-Bolt Mongo-Bolt is a lightweight, modern MongoDB wrapper built on top of Mongoose, designed to simplify database operations with an intuitive, beginner-friendly API. It provides robust tools for connecting to MongoDB, managing collections, performing CRUD operations, handling transactions, building aggregation pipelines, and managing indexes. With inbuilt caching, simplified joins, and streamlined indexing, Mongo-Bolt is ideal for Node.js developers building efficient and scalable applications. Inspired by the clarity and interactivity of Docs by Hashnode, this documentation offers a modular, developer-centric guide to Mongo-Bolt. The `AggregationBuilder` class simplifies MongoDB’s complex aggregation pipelines, making them accessible to beginners and powerful for advanced users. Whether you're new to MongoDB or an experienced developer, Mongo-Bolt empowers you to work with MongoDB efficiently. ## Why Mongo-Bolt? Mongo-Bolt stands out with features tailored to enhance developer experience and performance: - **Beginner-Friendly**: Intuitive method names, clear error messages, and a streamlined API reduce the learning curve for MongoDB. - **Inbuilt Caching**: Improves performance for repeated queries by caching results (implementation details to be covered in a forthcoming blog). - **Simplified Joins, Indexing, and Multi-Collection Fetching**: Methods like `findAndPopulateById`, `findAndPopulateByKey`, and index management make complex operations straightforward. ## Table of Contents - [Installation](#installation) - [Getting Started](#getting-started) - [Configuration](#configuration) - [Methods](#methods) - [MongoDB Class Methods](#mongodb-class-methods) - [connect](#connect) - [createStore](#createstore) - [insertItem](#insertitem) - [insertItems](#insertitems) - [findItem](#finditem) - [updateItems](#updateitems) - [deleteStore](#deletestore) - [dropItem](#dropitem) - [dropItems](#dropitems) - [truncateStore](#truncatestore) - [alterStore](#alterstore) - [findAndPopulateById](#findandpopulatebyid) - [aggregate](#aggregate) - [pipelineBuilder](#pipelinebuilder) - [createIndex](#createindex) - [viewIndexes](#viewindexes) - [dropIndex](#dropindex) - [findAndPopulateByKey](#findandpopulatebykey) - [startTransaction](#starttransaction) - [commitTransaction](#committransaction) - [abortTransaction](#aborttransaction) - [getSession](#getsession) - [getMongoose](#getmongoose) - [disconnect](#disconnect) - [AggregationBuilder Methods](#aggregationbuilder-methods) - [match](#match) - [group](#group) - [sum](#sum) - [avg](#avg) - [min](#min) - [max](#max) - [first](#first) - [last](#last) - [push](#push) - [addToSet](#addtoset) - [stdDevPop](#stddevpop) - [stdDevSamp](#stddevsamp) - [mergeObjects](#mergeobjects) - [count](#count) - [project](#project) - [sort](#sort) - [limit](#limit) - [skip](#skip) - [lookup](#lookup) - [unset](#unset) - [addFields](#addfields) - [replaceRoot](#replaceroot) - [replaceWith](#replacewith) - [graphLookup](#graphlookup) - [unwind](#unwind) - [bucket](#bucket) - [bucketAuto](#bucketauto) - [facet](#facet) - [merge](#merge) - [out](#out) - [search](#search) - [searchMeta](#searchmeta) - [redact](#redact) - [indexStats](#indexstats) - [currentOp](#currentop) - [collStats](#collstats) - [planCacheStats](#plancachestats) - [listSessions](#listsessions) - [build](#build) - [Advanced Usage](#advanced-usage) - [Transaction Management](#transaction-management) - [Aggregation Pipelines](#aggregation-pipelines) - [Index Management](#index-management) - [Examples](#examples) - [Complete CRUD Workflow](#complete-crud-workflow) - [Populating Related Data](#populating-related-data) - [Building an Aggregation Pipeline](#building-an-aggregation-pipeline) - [Error Handling](#error-handling) - [Contributing](#contributing) - [License](#license) ## Installation Install Mongo-Bolt via npm: ```bash npm install mongo-bolt ``` Mongo-Bolt requires Mongoose as a peer dependency. Install it if not already present: ```bash npm install mongoose ``` ## Getting Started To start using Mongo-Bolt, import the `MongoDB` class, configure your MongoDB connection, and connect to your database: ```javascript import MongoDB from 'mongo-bolt'; const config = { uri: 'mongodb://localhost:27017/mydb', options: { useNewUrlParser: true, useUnifiedTopology: true, }, }; const db = new MongoDB(config); async function init() { try { await db.connect(); console.log('Connected to MongoDB'); } catch (error) { console.error('Connection failed:', error.message); } } init(); ``` This example showcases Mongo-Bolt’s beginner-friendly setup, inspired by Hashnode Docs’ intuitive onboarding. ## Configuration The `MongoDB` constructor accepts a `config` object with the following properties: | Property | Type | Description | Required | |-----------|----------|-----------------------------------------------------------------------------|----------| | `uri` | `string` | MongoDB connection URI (e.g., `mongodb://localhost:27017/mydb`) | Yes | | `options` | `object` | Mongoose connection options (e.g., `{ useNewUrlParser: true }`) | No | **Example:** ```javascript const config = { uri: 'mongodb://localhost:27017/mydb', options: { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 5000, }, }; ``` ## Methods Mongo-Bolt provides two primary interfaces: the `MongoDB` class for core database operations and the `AggregationBuilder` class for constructing aggregation pipelines. Each method is documented with its signature, parameters, return value, and an example, ensuring clarity and interactivity akin to Hashnode Docs. ### MongoDB Class Methods #### connect Establishes a connection to the MongoDB database. **Signature:** ```javascript async connect(): Promise<void> ``` **Returns:** - `Promise<void>`: Resolves when the connection is successful, or rejects with an error. **Example:** ```javascript const db = new MongoDB(config); await db.connect(); console.log('Database connected'); ``` #### createStore Creates a new collection with a specified schema. **Signature:** ```javascript async createStore<T>( collectionName: string, schema: SchemaDefinition<SchemaDefinitionType<T>> ): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|-----------------------------------|-------------------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to create. | Yes | | `schema` | `SchemaDefinition<SchemaDefinitionType<T>>` | Mongoose schema definition for the collection. | Yes | **Returns:** - `Promise<void>`: Resolves when the collection is created, or rejects with an error. **Example:** ```javascript import { Schema } from 'mongoose'; const userSchema = { name: { type: String, required: true }, email: { type: String, required: true, unique: true }, }; const db = new MongoDB(config); await db.connect(); await db.createStore('users', userSchema); console.log('Users collection created'); ``` #### insertItem Inserts a single document into a collection. **Signature:** ```javascript async insertItem<T>(collectionName: string, documentData: T): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|----------|----------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to insert into. | Yes | | `documentData` | `T` | The document data to insert. | Yes | **Returns:** - `Promise<void>`: Resolves when the document is inserted, or rejects with an error. **Example:** ```javascript const user = { name: 'John Doe', email: 'john@example.com', }; await db.insertItem('users', user); console.log('User inserted'); ``` #### insertItems Inserts multiple documents into a collection. **Signature:** ```javascript async insertItems<T>(collectionName: string, documentsData: T[]): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|----------|----------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to insert into. | Yes | | `documentsData` | `T[]` | Array of document data to insert. | Yes | **Returns:** - `Promise<void>`: Resolves when all documents are inserted, or rejects with an error. **Example:** ```javascript const users = [ { name: 'Jane Doe', email: 'jane@example.com' }, { name: 'Bob Smith', email: 'bob@example.com' }, ]; await db.insertItems('users', users); console.log('Users inserted'); ``` #### findItem Retrieves documents from a collection based on a query. **Signature:** ```javascript async findItem<T>( collectionName: string, query: Record<string, any> = {} ): Promise<T[]> ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|-------------------------|----------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to query. | Yes | | `query` | `Record<string, any>` | Query object to filter documents (default: `{}`). | No | **Returns:** - `Promise<T[]>`: An array of documents matching the query. **Example:** ```javascript const users = await db.findItem('users', { name: 'John Doe' }); console.log(users); // [{ name: 'John Doe', email: 'john@example.com', ... }] ``` #### updateItems Updates multiple documents in a collection based on a query. **Signature:** ```javascript async updateItems( collectionName: string, query: Record<string, any>, update: Record<string, any> ): Promise<number> ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|-------------------------|----------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to update. | Yes | | `query` | `Record<string, any>` | Query to select documents to update. | Yes | | `update` | `Record<string, any>` | Update operations to apply (e.g., `{ $set: { ... } }`). | Yes | **Returns:** - `Promise<number>`: The number of documents updated. **Example:** ```javascript const updatedCount = await db.updateItems( 'users', { name: 'John Doe' }, { $set: { email: 'john.doe@example.com' } } ); console.log(`${updatedCount} users updated`); ``` #### deleteStore Deletes a collection from the database. **Signature:** ```javascript async deleteStore(collectionName: string): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|----------|----------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to delete. | Yes | **Returns:** - `Promise<void>`: Resolves when the collection is deleted, or rejects with an error. **Example:** ```javascript await db.deleteStore('users'); console.log('Users collection deleted'); ``` #### dropItem Deletes a single document from a collection based on a query. **Signature:** ```javascript async dropItem( storeName: string, itemInfo: Record<string, any> ): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |--------------|-------------------------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to delete from. | Yes | | `itemInfo` | `Record<string, any>` | Query to identify the document to delete. | Yes | **Returns:** - `Promise<void>`: Resolves when the document is deleted, or rejects with an error. **Example:** ```javascript await db.dropItem('users', { email: 'john@example.com' }); console.log('User dropped'); ``` #### dropItems Deletes multiple documents from a collection based on a query. **Signature:** ```javascript async dropItems( storeName: string, itemInfo: Record<string, any> ): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |--------------|-------------------------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to delete from. | Yes | | `itemInfo` | `Record<string, any>` | Query to identify documents to delete. | Yes | **Returns:** - `Promise<void>`: Resolves when the documents are deleted, or rejects with an error. **Example:** ```javascript await db.dropItems('users', { name: 'John Doe' }); console.log('Users dropped'); ``` #### truncateStore Removes all documents from a collection without deleting the collection itself. **Signature:** ```javascript async truncateStore(storeName: string): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |--------------|----------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to truncate. | Yes | **Returns:** - `Promise<void>`: Resolves when the collection is truncated, or rejects with an error. **Example:** ```javascript await db.truncateStore('users'); console.log('Users collection truncated'); ``` #### alterStore Modifies the schema of an existing collection and updates documents as needed. **Signature:** ```javascript async alterStore<T, U>( storeName: string, newSchema: SchemaDefinition<SchemaDefinitionType<U>>, changeValues: Record<string, any> ): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |----------------|-----------------------------------|-------------------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to modify. | Yes | | `newSchema` | `SchemaDefinition<SchemaDefinitionType<U>>` | New schema definition for the collection. | Yes | | `changeValues` | `Record<string, any>` | Update operations to apply to existing documents. | Yes | **Returns:** - `Promise<void>`: Resolves when the schema is updated, or rejects with an error. **Example:** ```javascript const newSchema = { name: { type: String, required: true }, email: { type: String, required: true }, age: { type: Number, default: 0 }, }; await db.alterStore('users', newSchema, { $set: { age: 18 } }); console.log('Users schema updated'); ``` #### findAndPopulateById Retrieves documents by ID and populates specified fields. **Signature:** ```javascript async findAndPopulateById<T>( storeName: string, thingsToBePopulated: string | string[], query: Record<string, any> ): Promise<T[]> ``` **Parameters:** | Parameter | Type | Description | Required | |-----------------------|-------------------------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to query. | Yes | | `thingsToBePopulated` | `string | string[]` | Field(s) to populate (e.g., `'posts'` or `['posts', 'comments']`). | Yes | | `query` | `Record<string, any>` | Query to filter documents (e.g., `{ _id: '123' }`). | Yes | **Returns:** - `Promise<T[]>`: An array of documents with populated fields. **Example:** ```javascript const user = await db.findAndPopulateById('users', 'posts', { _id: '123' }); console.log(user); // [{ name: 'John', posts: [{ title: 'Post 1', ... }, ...] }] ``` #### aggregate Executes an aggregation pipeline on a collection. **Signature:** ```javascript async aggregate<T>( storeName: string, pipeline: any ): Promise<any[]> ``` **Parameters:** | Parameter | Type | Description | Required | |--------------|----------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to aggregate. | Yes | | `pipeline` | `any` | Array of aggregation pipeline stages. | Yes | **Returns:** - `Promise<any[]>`: An array of aggregation results. **Example:** ```javascript const pipeline = [ { $match: { name: 'John Doe' } }, { $group: { _id: '$email', count: { $sum: 1 } } }, ]; const results = await db.aggregate('users', pipeline); console.log(results); // [{ _id: 'john@example.com', count: 1 }, ...] ``` #### pipelineBuilder Creates an instance of `AggregationBuilder` for constructing aggregation pipelines. **Signature:** ```javascript pipelineBuilder(): AggregationBuilder ``` **Returns:** - `AggregationBuilder`: An instance of the aggregation builder. **Example:** ```javascript const builder = db.pipelineBuilder(); const pipeline = builder .match('status', { eq: 'active' }) .group('userId') .sum('amount', 'totalSpent') .build(); const results = await db.aggregate('orders', pipeline); console.log(results); ``` #### createIndex Creates an index on a specified column in a collection. **Signature:** ```javascript async createIndex( storeName: string, column: string, order: string, options: any ): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |-------------|----------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to create the index on. | Yes | | `column` | `string` | Field to index (e.g., `'email'`). | Yes | | `order` | `string` | Index order (e.g., `'1'` for ascending, `'-1'` for descending). | Yes | | `options` | `any` | Additional index options (e.g., `{ unique: true }`). | Yes | **Returns:** - `Promise<void>`: Resolves when the index is created, or rejects with an error. **Example:** ```javascript await db.createIndex('users', 'email', '1', { unique: true }); console.log('Index created on email'); ``` #### viewIndexes Retrieves all indexes for a collection. **Signature:** ```javascript async viewIndexes(storeName: string): Promise<IndexDefinition[]> ``` **Parameters:** | Parameter | Type | Description | Required | |-------------|----------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to view indexes for. | Yes | **Returns:** - `Promise<IndexDefinition[]>`: An array of index definitions. **Example:** ```javascript const indexes = await db.viewIndexes('users'); console.log(indexes); // [{ key: { email: 1 }, name: 'email_1', ... }, ...] ``` #### dropIndex Drops a specified index from a collection. **Signature:** ```javascript async dropIndex(storeName: string, indexName: string): Promise<void> ``` **Parameters:** | Parameter | Type | Description | Required | |--------------|----------|----------------------------------------------------------|----------| | `storeName` | `string` | Name of the collection to drop the index from. | Yes | | `indexName` | `string` | Name of the index to drop (e.g., `'email_1'`). | Yes | **Returns:** - `Promise<void>`: Resolves when the index is dropped, or rejects with an error. **Example:** ```javascript await db.dropIndex('users', 'email_1'); console.log('Index dropped'); ``` #### findAndPopulateByKey Retrieves documents from one collection and populates fields from another collection based on a key relationship. **Signature:** ```javascript async findAndPopulateByKey( fromStoreName: string, query: Record<string, any>, fromKey: string, findInStoreName: string, inKey: string ): Promise<any[]> ``` **Parameters:** | Parameter | Type | Description | Required | |-------------------|-------------------------|----------------------------------------------------------|----------| | `fromStoreName` | `string` | Name of the source collection. | Yes | | `query` | `Record<string, any>` | Query to filter source documents. | Yes | | `fromKey` | `string` | Field in the source collection to match. | Yes | | `findInStoreName` | `string` | Name of the collection to populate from. | Yes | | `inKey` | `string` | Field in the target collection to match against `fromKey`. | Yes | **Returns:** - `Promise<any[]>`: An array of documents with populated fields. **Example:** ```javascript const users = await db.findAndPopulateByKey( 'users', { name: 'John Doe' }, 'userId', 'posts', 'authorId' ); console.log(users); // [{ name: 'John Doe', posts: [{ title: 'Post 1', ... }, ...] }] ``` #### startTransaction Starts a new transaction session. **Signature:** ```javascript async startTransaction(): Promise<void> ``` **Returns:** - `Promise<void>`: Resolves when the transaction session is started, or rejects with an error. **Example:** ```javascript await db.startTransaction(); console.log('Transaction started'); ``` #### commitTransaction Commits the current transaction. **Signature:** ```javascript async commitTransaction(): Promise<void> ``` **Returns:** - `Promise<void>`: Resolves when the transaction is committed, or rejects with an error. **Example:** ```javascript await db.commitTransaction(); console.log('Transaction committed'); ``` #### abortTransaction Aborts the current transaction. **Signature:** ```javascript async abortTransaction(): Promise<void> ``` **Returns:** - `Promise<void>`: Resolves when the transaction is aborted, or rejects with an error. **Example:** ```javascript await db.abortTransaction(); console.log('Transaction aborted'); ``` #### getSession Retrieves the current Mongoose session, if one exists. **Signature:** ```javascript async getSession(): Promise<mongoose.ClientSession | null> ``` **Returns:** - `Promise<mongoose.ClientSession | null>`: The current session or `null` if no session exists. **Example:** ```javascript const session = await db.getSession(); if (session) { console.log('Active session retrieved'); } else { console.log('No active session'); } ``` #### getMongoose Retrieves the Mongoose instance used by the wrapper. **Signature:** ```javascript async getMongoose(): Promise<typeof mongoose> ``` **Returns:** - `Promise<typeof mongoose>`: The Mongoose instance. **Example:** ```javascript const mongoose = await db.getMongoose(); console.log('Mongoose instance retrieved:', mongoose.version); ``` #### disconnect Closes the connection to the MongoDB database. **Signature:** ```javascript async disconnect(): Promise<void> ``` **Returns:** - `Promise<void>`: Resolves when the connection is closed, or rejects with an error. **Example:** ```javascript await db.disconnect(); console.log('Database disconnected'); ``` ### AggregationBuilder Methods The `AggregationBuilder` class simplifies MongoDB’s aggregation pipelines with a fluent, chainable API. It supports a comprehensive set of pipeline stages and operators, making complex data transformations accessible to beginners and powerful for advanced users. Below are the methods provided in the class, each with a description, parameters, and example. #### match Filters documents based on a field and condition, using a mapped operator (e.g., `eq`, `gt`) from `operatorMap`. **Signature:** ```javascript match(field: string, condition: Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |-------------|-------------------------|----------------------------------------------------------|----------| | `field` | `string` | Field to filter on. | Yes | | `condition` | `Record<string, any>` | Condition object with operators (e.g., `{ eq: 'active' }`). | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .match('status', { eq: 'active' }) .build(); ``` #### group Groups documents by a field or composite key, enabling accumulator operations. **Signature:** ```javascript group(groupBy: string | Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |------------|-------------------------|----------------------------------------------------------|----------| | `groupBy` | `string | Record<string, any>` | Field name or object for composite grouping key. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .build(); ``` #### sum Adds a `$sum` accumulator to the last group stage. **Signature:** ```javascript sum(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to sum. | Yes | | `key` | `string` | Output field name for the sum. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .sum('amount', 'totalSpent') .build(); ``` #### avg Adds an `$avg` accumulator to the last group stage. **Signature:** ```javascript avg(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to average. | Yes | | `key` | `string` | Output field name for the average. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .avg('score', 'averageScore') .build(); ``` #### min Adds a `$min` accumulator to the last group stage. **Signature:** ```javascript min(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to find the minimum of. | Yes | | `key` | `string` | Output field name for the minimum. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .min('price', 'minPrice') .build(); ``` #### max Adds a `$max` accumulator to the last group stage. **Signature:** ```javascript max(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to find the maximum of. | Yes | | `key` | `string` | Output field name for the maximum. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .max('price', 'maxPrice') .build(); ``` #### first Adds a `$first` accumulator to the last group stage. **Signature:** ```javascript first(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to select the first value of. | Yes | | `key` | `string` | Output field name for the first value. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .first('name', 'firstName') .build(); ``` #### last Adds a `$last` accumulator to the last group stage. **Signature:** ```javascript last(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to select the last value of. | Yes | | `key` | `string` | Output field name for the last value. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .last('name', 'lastName') .build(); ``` #### push Adds a `$push` accumulator to the last group stage, collecting values into an array. **Signature:** ```javascript push(field: string, key: string = field): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `field` | `string` | Field to collect (or `'ENTIRE'` for the entire document). | Yes | | `key` | `string` | Output field name for the array (defaults to `field`). | No | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .push('orderId', 'orders') .build(); ``` #### addToSet Adds an `$addToSet` accumulator to the last group stage, collecting unique values into an array. **Signature:** ```javascript addToSet(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to collect unique values from. | Yes | | `key` | `string` | Output field name for the unique array. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .addToSet('category', 'categories') .build(); ``` #### stdDevPop Adds a `$stdDevPop` accumulator to the last group stage for population standard deviation. **Signature:** ```javascript stdDevPop(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to calculate population standard deviation. | Yes | | `key` | `string` | Output field name for the result. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .stdDevPop('score', 'scoreStdDevPop') .build(); ``` #### stdDevSamp Adds a `$stdDevSamp` accumulator to the last group stage for sample standard deviation. **Signature:** ```javascript stdDevSamp(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field to calculate sample standard deviation. | Yes | | `key` | `string` | Output field name for the result. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .stdDevSamp('score', 'scoreStdDevSamp') .build(); ``` #### mergeObjects Adds a `$mergeObjects` accumulator to the last group stage to combine documents. **Signature:** ```javascript mergeObjects(value: string, key: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `value` | `string` | Field containing objects to merge. | Yes | | `key` | `string` | Output field name for the merged object. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .mergeObjects('details', 'mergedDetails') .build(); ``` #### count Adds a `$sum: 1` accumulator to the last group stage to count documents. **Signature:** ```javascript count(key: string = 'count'): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `key` | `string` | Output field name for the count (defaults to `'count'`). | No | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .group('userId') .count('userCount') .build(); ``` #### project Specifies fields to include or exclude in the output. **Signature:** ```javascript project(projection: Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |--------------|-------------------------|----------------------------------------------------------|----------| | `projection` | `Record<string, any>` | Object specifying fields to include (1) or exclude (0). | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .project({ name: 1, email: 1, _id: 0 }) .build(); ``` #### sort Sorts documents by specified fields. **Signature:** ```javascript sort(sortFields: Record<string, 'asc' | 'desc'>): this ``` **Parameters:** | Parameter | Type | Description | Required | |---------------|-----------------------------------|----------------------------------------------------------|----------| | `sortFields` | `Record<string, 'asc' | 'desc'>` | Object mapping fields to sort direction (`asc` or `desc`). | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .sort({ totalSpent: 'desc' }) .build(); ``` #### limit Limits the number of documents returned. **Signature:** ```javascript limit(n: number): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `n` | `number` | Maximum number of documents to return. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .limit(10) .build(); ``` #### skip Skips a specified number of documents. **Signature:** ```javascript skip(n: number): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|----------|----------------------------------------------------------|----------| | `n` | `number` | Number of documents to skip. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .skip(5) .build(); ``` #### lookup Performs a left outer join with another collection. **Signature:** ```javascript lookup(from: string, localField: string, foreignField: string, as: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |----------------|----------|----------------------------------------------------------|----------| | `from` | `string` | Name of the collection to join with. | Yes | | `localField` | `string` | Field from the input documents. | Yes | | `foreignField` | `string` | Field from the `from` collection. | Yes | | `as` | `string` | Name of the output array field. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .lookup('posts', 'userId', 'authorId', 'userPosts') .build(); ``` #### unset Removes specified fields from documents. **Signature:** ```javascript unset(...fields: string[]): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|------------|----------------------------------------------------------|----------| | `fields` | `string[]` | Fields to remove from documents. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .unset('password', 'token') .build(); ``` #### addFields Adds new fields to documents. **Signature:** ```javascript addFields(fields: Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|-------------------------|----------------------------------------------------------|----------| | `fields` | `Record<string, any>` | Object specifying new fields and their values. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .addFields({ fullName: { $concat: ['$firstName', ' ', '$lastName'] } }) .build(); ``` #### replaceRoot Replaces the document with a specified new root. **Signature:** ```javascript replaceRoot(newRoot: any): this ``` **Parameters:** | Parameter | Type | Description | Required | |------------|----------|----------------------------------------------------------|----------| | `newRoot` | `any` | Expression defining the new root document. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .replaceRoot('$details') .build(); ``` #### replaceWith Replaces the document with a specified value. **Signature:** ```javascript replaceWith(replacement: any): this ``` **Parameters:** | Parameter | Type | Description | Required | |---------------|----------|----------------------------------------------------------|----------| | `replacement` | `any` | Expression defining the replacement document. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .replaceWith('$details') .build(); ``` #### graphLookup Performs a recursive search on a collection. **Signature:** ```javascript graphLookup(options: { from: string; startWith: any; connectFromField: string; connectToField: string; as: string; maxDepth?: number; depthField?: string; restrictSearchWithMatch?: Record<string, any>; }): this ``` **Parameters:** | Parameter | Type | Description | Required | |----------------------------|-------------------------|----------------------------------------------------------|----------| | `options.from` | `string` | Collection to perform the lookup on. | Yes | | `options.startWith` | `any` | Expression to start the graph lookup. | Yes | | `options.connectFromField` | `string` | Field to connect from. | Yes | | `options.connectToField` | `string` | Field to connect to. | Yes | | `options.as` | `string` | Output array field name. | Yes | | `options.maxDepth` | `number` | Maximum recursion depth (optional). | No | | `options.depthField` | `string` | Field to store depth (optional). | No | | `options.restrictSearchWithMatch` | `Record<string, any>` | Match conditions to restrict search (optional). | No | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .graphLookup({ from: 'employees', startWith: '$managerId', connectFromField: 'managerId', connectToField: '_id', as: 'reportingHierarchy', }) .build(); ``` #### unwind Deconstructs an array field into multiple documents. **Signature:** ```javascript unwind(field: string | Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|-------------------------|----------------------------------------------------------|----------| | `field` | `string | Record<string, any>` | Field to unwind or unwind options object. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .unwind('items') .build(); ``` #### bucket Groups documents into buckets based on a specified expression. **Signature:** ```javascript bucket(options: { groupBy: any; boundaries: any[]; default?: any; output: Record<string, any>; }): this ``` **Parameters:** | Parameter | Type | Description | Required | |---------------------|-------------------------|----------------------------------------------------------|----------| | `options.groupBy` | `any` | Expression to group by. | Yes | | `options.boundaries`| `any[]` | Array of bucket boundaries. | Yes | | `options.default` | `any` | Default bucket for non-matching documents (optional). | No | | `options.output` | `Record<string, any>` | Output specification for each bucket. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .bucket({ groupBy: '$price', boundaries: [0, 100, 200, 300], default: 'other', output: { count: { $sum: 1 } }, }) .build(); ``` #### bucketAuto Automatically groups documents into a specified number of buckets. **Signature:** ```javascript bucketAuto(options: { groupBy: any; buckets: number; output?: Record<string, any>; granularity?: string; }): this ``` **Parameters:** | Parameter | Type | Description | Required | |----------------------|-------------------------|----------------------------------------------------------|----------| | `options.groupBy` | `any` | Expression to group by. | Yes | | `options.buckets` | `number` | Number of buckets. | Yes | | `options.output` | `Record<string, any>` | Output specification for each bucket (optional). | No | | `options.granularity`| `string` | Granularity for numeric bucketing (optional). | No | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .bucketAuto({ groupBy: '$price', buckets: 5, output: { count: { $sum: 1 } }, }) .build(); ``` #### facet Processes multiple aggregation pipelines within a single stage. **Signature:** ```javascript facet(facets: Record<string, any[]>): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|-------------------------|----------------------------------------------------------|----------| | `facets` | `Record<string, any[]>` | Object mapping facet names to pipeline arrays. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .facet({ byCategory: [{ $group: { _id: '$category', count: { $sum: 1 } } }], byPrice: [{ $bucket: { groupBy: '$price', boundaries: [0, 100, 200] } }], }) .build(); ``` #### merge Writes the results of the pipeline to a collection. **Signature:** ```javascript merge(options: string | Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |-----------|-------------------------|----------------------------------------------------------|----------| | `options` | `string | Record<string, any>` | Collection name or merge options object. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .merge('outputCollection') .build(); ``` #### out Writes the pipeline results to a collection, replacing its contents. **Signature:** ```javascript out(collectionName: string): this ``` **Parameters:** | Parameter | Type | Description | Required | |------------------|----------|----------------------------------------------------------|----------| | `collectionName` | `string` | Name of the collection to write to. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .out('results') .build(); ``` #### search Adds a `$search` stage for Atlas Search. **Signature:** ```javascript search(searchStage: Record<string, any>): this ``` **Parameters:** | Parameter | Type | Description | Required | |---------------|-------------------------|----------------------------------------------------------|----------| | `searchStage` | `Record<string, any>` | Search stage configuration. | Yes | **Returns:** - `this`: The `AggregationBuilder` instance for chaining. **Example:** ```javascript const pipeline = db.pipelineBuilder() .search({ text: { query: 'example', path: 'description' } })