A lightweight, beginner-friendly MongoDB wrapper with inbuilt caching and simplified joins/indexing.
npm install mongo-boltMongo-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.
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.
- Installation
- Getting Started
- Configuration
- Methods
- MongoDB Class Methods
- connect
- createStore
- insertItem
- insertItems
- findItem
- updateItems
- deleteStore
- dropItem
- dropItems
- truncateStore
- alterStore
- findAndPopulateById
- aggregate
- pipelineBuilder
- createIndex
- viewIndexes
- dropIndex
- findAndPopulateByKey
- startTransaction
- commitTransaction
- abortTransaction
- getSession
- getMongoose
- disconnect
- AggregationBuilder Methods
- match
- group
- sum
- avg
- min
- max
- first
- last
- push
- addToSet
- stdDevPop
- stdDevSamp
- mergeObjects
- count
- project
- sort
- limit
- skip
- lookup
- unset
- addFields
- replaceRoot
- replaceWith
- graphLookup
- unwind
- bucket
- bucketAuto
- facet
- merge
- out
- search
- searchMeta
- redact
- indexStats
- currentOp
- collStats
- planCacheStats
- listSessions
- build
- Advanced Usage
- Transaction Management
- Aggregation Pipelines
- Index Management
- Examples
- Complete CRUD Workflow
- Populating Related Data
- Building an Aggregation Pipeline
- Error Handling
- Contributing
- License
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
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.
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,
},
};
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.
#### connect
Establishes a connection to the MongoDB database.
Signature:
`javascript`
async connect(): Promise
Returns:
- Promise: 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
collectionName: string,
schema: SchemaDefinition
): Promise
Parameters:
| Parameter | Type | Description | Required |
|------------------|-----------------------------------|-------------------------------------------------------------------|----------|
| collectionName | string | Name of the collection to create. | Yes |schema
| | SchemaDefinition | Mongoose schema definition for the collection. | Yes |
Returns:
- Promise: 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
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: 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
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: 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
collectionName: string,
query: Record
): Promise
Parameters:
| Parameter | Type | Description | Required |
|------------------|-------------------------|----------------------------------------------------------|----------|
| collectionName | string | Name of the collection to query. | Yes |query
| | Record | Query object to filter documents (default: {}). | No |
Returns:
- Promise: 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
update: Record
): Promise
Parameters:
| Parameter | Type | Description | Required |
|------------------|-------------------------|----------------------------------------------------------|----------|
| collectionName | string | Name of the collection to update. | Yes |query
| | Record | Query to select documents to update. | Yes |update
| | Record | Update operations to apply (e.g., { $set: { ... } }). | Yes |
Returns:
- Promise: The number of documents updated.
Example:
`javascript${updatedCount} users updated
const updatedCount = await db.updateItems(
'users',
{ name: 'John Doe' },
{ $set: { email: 'john.doe@example.com' } }
);
console.log();`
#### deleteStore
Deletes a collection from the database.
Signature:
`javascript`
async deleteStore(collectionName: string): Promise
Parameters:
| Parameter | Type | Description | Required |
|------------------|----------|----------------------------------------------------------|----------|
| collectionName | string | Name of the collection to delete. | Yes |
Returns:
- Promise: 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
): Promise
Parameters:
| Parameter | Type | Description | Required |
|--------------|-------------------------|----------------------------------------------------------|----------|
| storeName | string | Name of the collection to delete from. | Yes |itemInfo
| | Record | Query to identify the document to delete. | Yes |
Returns:
- Promise: 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
): Promise
Parameters:
| Parameter | Type | Description | Required |
|--------------|-------------------------|----------------------------------------------------------|----------|
| storeName | string | Name of the collection to delete from. | Yes |itemInfo
| | Record | Query to identify documents to delete. | Yes |
Returns:
- Promise: 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
Parameters:
| Parameter | Type | Description | Required |
|--------------|----------|----------------------------------------------------------|----------|
| storeName | string | Name of the collection to truncate. | Yes |
Returns:
- Promise: 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
storeName: string,
newSchema: SchemaDefinition
changeValues: Record
): Promise
Parameters:
| Parameter | Type | Description | Required |
|----------------|-----------------------------------|-------------------------------------------------------------------|----------|
| storeName | string | Name of the collection to modify. | Yes |newSchema
| | SchemaDefinition | New schema definition for the collection. | Yes |changeValues
| | Record | Update operations to apply to existing documents. | Yes |
Returns:
- Promise: 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
storeName: string,
thingsToBePopulated: string | string[],
query: Record
): Promise
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 | Query to filter documents (e.g., { _id: '123' }). | Yes |
Returns:
- Promise: 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
storeName: string,
pipeline: any
): Promise
Parameters:
| Parameter | Type | Description | Required |
|--------------|----------|----------------------------------------------------------|----------|
| storeName | string | Name of the collection to aggregate. | Yes |pipeline
| | any | Array of aggregation pipeline stages. | Yes |
Returns:
- Promise: 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
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: 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
Parameters:
| Parameter | Type | Description | Required |
|-------------|----------|----------------------------------------------------------|----------|
| storeName | string | Name of the collection to view indexes for. | Yes |
Returns:
- Promise: 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
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: 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
fromKey: string,
findInStoreName: string,
inKey: string
): Promise
Parameters:
| Parameter | Type | Description | Required |
|-------------------|-------------------------|----------------------------------------------------------|----------|
| fromStoreName | string | Name of the source collection. | Yes |query
| | Record | 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: 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
Returns:
- Promise: 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
Returns:
- Promise: 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
Returns:
- Promise: 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
Returns:
- Promise: 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
Returns:
- Promise: 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
Returns:
- Promise: Resolves when the connection is closed, or rejects with an error.
Example:
`javascript`
await db.disconnect();
console.log('Database disconnected');
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
Parameters:
| Parameter | Type | Description | Required |
|-------------|-------------------------|----------------------------------------------------------|----------|
| field | string | Field to filter on. | Yes |condition
| | Record | 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
Parameters:
| Parameter | Type | Description | Required |
|------------|-------------------------|----------------------------------------------------------|----------|
| groupBy | string | Record | 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
Parameters:
| Parameter | Type | Description | Required |
|--------------|-------------------------|----------------------------------------------------------|----------|
| projection | Record | 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
Parameters:
| Parameter | Type | Description | Required |
|---------------|-----------------------------------|----------------------------------------------------------|----------|
| sortFields | Record | 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
Parameters:
| Parameter | Type | Description | Required |
|-----------|-------------------------|----------------------------------------------------------|----------|
| fields | Record | 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
}): 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 | 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
Parameters:
| Parameter | Type | Description | Required |
|-----------|-------------------------|----------------------------------------------------------|----------|
| field | string | Record | 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
}): 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 | 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
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 | 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
Parameters:
| Parameter | Type | Description | Required |
|-----------|-------------------------|----------------------------------------------------------|----------|
| facets | Record | 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
Parameters:
| Parameter | Type | Description | Required |
|-----------|-------------------------|----------------------------------------------------------|----------|
| options | string | Record | 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
Parameters:
| Parameter | Type | Description | Required |
|---------------|-------------------------|----------------------------------------------------------|----------|
| searchStage | Record | Search stage configuration. | Yes |
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.search({ text: { query: 'example', path: 'description' } })
.build();
#### searchMeta
Adds a $searchMeta stage for Atlas Search metadata.
Signature:
`javascript`
searchMeta(searchStage: Record
Parameters:
| Parameter | Type | Description | Required |
|---------------|-------------------------|----------------------------------------------------------|----------|
| searchStage | Record | Search metadata stage configuration. | Yes |
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.searchMeta({ count: { type: 'total' } })
.build();
#### redact
Restricts document content based on an expression.
Signature:
`javascript`
redact(expression: any): this
Parameters:
| Parameter | Type | Description | Required |
|--------------|----------|----------------------------------------------------------|----------|
| expression | any | Redaction expression (e.g., $cond). | Yes |
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.redact({
$cond: { if: { $eq: ['$level', 'public'] }, then: '$$KEEP', else: '$$PRUNE' },
})
.build();
#### indexStats
Adds an $indexStats stage to retrieve index statistics.
Signature:
`javascript`
indexStats(): this
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.indexStats()
.build();
#### currentOp
Adds a $currentOp stage to retrieve current operations.
Signature:
`javascript`
currentOp(): this
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.currentOp()
.build();
#### collStats
Adds a $collStats stage to retrieve collection statistics.
Signature:
`javascript`
collStats(): this
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.collStats()
.build();
#### planCacheStats
Adds a $planCacheStats stage to retrieve query plan cache statistics.
Signature:
`javascript`
planCacheStats(): this
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.planCacheStats()
.build();
#### listSessions
Adds a $listSessions stage to retrieve active sessions.
Signature:
`javascript`
listSessions(): this
Returns:
- this: The AggregationBuilder instance for chaining.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.listSessions()
.build();
#### build
Returns the constructed aggregation pipeline.
Signature:
`javascript`
build(): any[]
Returns:
- any[]: The array of pipeline stages.
Example:
`javascript`
const pipeline = db.pipelineBuilder()
.match('status', { eq: 'active' })
.group('userId')
.sum('amount', 'totalSpent')
.build();
console.log(pipeline); // [{ $match: ... }, { $group: ... }]
Mongo-Bolt supports advanced MongoDB features, making it suitable for complex applications. The following sections, inspired by Hashnode Docs’ focus on interactivity, provide guidance on leveraging these capabilities.
Mongo-Bolt supports MongoDB transactions for atomic operations across multiple collections. Use startTransaction, commitTransaction, abortTransaction, and getSession to manage transactions.
Example:
`javascript
const db = new MongoDB(config);
await db.connect();
try {
await db.startTransaction();
const session = await db.getSession();
const user = { name: 'Alice', email: 'alice@example.com' };
await db.insertItem('users', user, { session });
const post = { title: 'First Post', author: 'Alice' };
await db.insertItem('posts', post, { session });
await db.commitTransaction();
console.log('Transaction committed');
} catch (error) {
await db.abortTransaction();
console.error('Transaction aborted:', error.message);
} finally {
await db.disconnect();
}
`
The aggregate method and AggregationBuilder enable powerful data aggregation. The AggregationBuilder provides a fluent interface, simplifying complex pipelines.
Example:
`javascript
const builder = db.pipelineBuilder();
const pipeline = builder
.match('status', { eq: 'active' })
.group('userId')
.sum('amount', 'totalSpent')
.sort({ totalSpent: 'desc' })
.limit(10)
.build();
const topSpenders = await db.aggregate('orders', pipeline);
console.log(topSpenders);
`
Indexes optimize query performance. Use createIndex, viewIndexes, and dropIndex to manage indexes.
Example:
`javascript
// Create a unique index
await db.createIndex('users', 'email', '1', { unique: true });
// View all indexes
const indexes = await db.viewIndexes('users');
console.log(indexes);
// Drop an index
await db.dropIndex('users', 'email_1');
console.log('Index dropped');
`
The following examples demonstrate Mongo-Bolt’s capabilities in real-world scenarios, designed to be interactive and clear, as inspired by Hashnode Docs.
This example shows a full CRUD workflow, from creating a collection to deleting a document.
`javascript
import MongoDB from 'mongo-bolt';
import { Schema } from 'mongoose';
const config = {
uri: 'mongodb://localhost:27017/mydb',
options: { useNewUrlParser: true, useUnifiedTopology: true },
};
const db = new MongoDB(config);
async function run() {
try {
// Connect to database
await db.connect();
// Create a collection
const userSchema = {
name: { type: String, required: true },
email: { type: String, required: true },
};
await db.createStore('users', userSchema);
// Insert a document
await db.insertItem('users', { name: 'Alice', email: 'alice@example.com' });
// Find documents
const users = await db.findItem('users', { name: 'Alice' });
console.log(users);
// Update documents
await db.updateItems('users', { name: 'Alice' }, { $set: { email: 'alice.new@example.com' } });
// Delete a document
await db.dropItem('users', { email: 'alice.new@example.com' });
// Disconnect
await db.disconnect();
} catch (error) {
console.error('Error:', error.message);
}
}
run();
`
This example demonstrates how to populate related data across collections.
`javascript
import MongoDB from 'mongo-bolt';
import { Schema } from 'mongoose';
const userSchema = {
name: { type: String, required: true },
postIds: [{ type: Schema.Types.ObjectId, ref: 'posts' }],
};
const postSchema = {
title: { type: String, required: true },
authorId: { type: Schema.Types.ObjectId, ref: 'users' },
};
const db = new MongoDB(config);
await db.connect();
await db.createStore('users', userSchema);
await db.createStore('posts', postSchema);
const users = await db.findAndPopulateById('users', 'postIds', { name: 'John' });
console.log(users); // [{ name: 'John', postIds: [{ title: 'Post 1', ... }, ...] }]
await db.disconnect();
`
This example shows how to use AggregationBuilder for advanced data analysis.
`javascript
const builder = db.pipelineBuilder();
const pipeline = builder
.match('status', { eq: 'active' })
.group('category')
.sum('price', 'total')
.sort({ total: 'desc' })
.limit(5)
.build();
const results = await db.aggregate('products', pipeline);
console.log(results); // [{ _id: 'electronics', total: 5000 }, ...]
`
Mongo-Bolt methods throw errors for invalid states (e.g., uninitialized connector) or database issues. Use try-catch blocks to handle errors, as recommended in robust documentation like Hashnode Docs.
Example:
`javascript`
try {
await db.insertItem('users', { name: 'Invalid User' });
} catch (error) {
console.error('Failed to insert user:', error.message);
}
Contributions to Mongo-Bolt are welcome! To contribute:
1. Fork the repository on GitHub.
2. Create a feature branch (git checkout -b feature/your-feature).git commit -m 'Add your feature'
3. Commit your changes ().git push origin feature/your-feature`).
4. Push to the branch (
5. Open a pull request.
Please include tests and update documentation for new features, aligning with the collaborative workflows emphasized by Hashnode Docs.
MIT License. See LICENSE for details.