Easy-Mongoo

Ultra-simple MongoDB wrapper with all mongoose features in easy syntax

Introduction

Easy-Mongoo is a powerful yet simple wrapper for MongoDB with Mongoose. It provides an intuitive API that makes database operations effortless while maintaining all the advanced features of Mongoose.

Why Easy-Mongoo? Traditional Mongoose can be complex for beginners. Easy-Mongoo simplifies everything while keeping all the power!

One-Line Operations

Perform complex database operations with just one line of code

Auto Error Handling

Automatic error handling with user-friendly messages

Smart Schema System

Create schemas with simple shortcuts and auto-features

All Mongoose Features

Virtuals, middleware, transactions, aggregation - everything included!

Installation

Install Easy-Mongoo using npm:

Terminal
npm install easy-mongoo

Then require it in your project:

JavaScript
const mongoo = require('easy-mongoo');

Quick Start

Get started with Easy-Mongoo in just 3 steps:

JavaScript
// 1. Connect to MongoDB await mongoo.connect('mongodb://localhost:27017/mydb'); // 2. Create a model with easy schema mongoo.model('User', { name: 'string!', email: 'email', age: 'number?' }); // 3. Use it! const user = await mongoo.create('User', { name: 'John Doe', email: 'john@example.com', age: 30 }); console.log(user);

That's it! You've just created a MongoDB connection, defined a schema, and saved a document with just a few lines of code.

Connection

Connect to MongoDB with automatic error handling and logging:

JavaScript
// Basic connection await mongoo.connect('mongodb://localhost:27017/mydb'); // With options and debug mode await mongoo.connect('mongodb://localhost:27017/mydb', { debug: true, useNewUrlParser: true, useUnifiedTopology: true }); // Check connection status const status = mongoo.status(); console.log(status); // Disconnect when done await mongoo.disconnect();

Connection Status Object

Property Description
connected Boolean indicating connection status
database Name of the connected database
host Database host address
models Array of registered model names
readyState Mongoose connection state

Schema Creation

Easy-Mongoo provides an ultra-simple schema system with smart shortcuts:

Basic Schema
Advanced Schema
All Shortcuts
JavaScript
// Simple schema with shortcuts const userSchema = { // Required string name: 'string!', // Optional number age: 'number?', // Boolean with default value isActive: 'boolean+', // Array of strings tags: ['string'], // Object with nested properties address: { street: 'string!', city: 'string!', country: 'string!' } };
JavaScript
// Advanced schema with validations const productSchema = { name: { type: 'string', required: true, minlength: [3, 'Name must be at least 3 characters'], maxlength: [50, 'Name cannot exceed 50 characters'] }, price: { type: 'number', required: true, min: [0, 'Price cannot be negative'] }, category: { type: 'string', enum: ['Electronics', 'Clothing', 'Books'], default: 'Electronics' }, inStock: { type: 'boolean', default: true } };
Shortcut Description Equivalent To
'string!' Required string { type: String, required: true }
'number?' Optional number Number
'boolean+' Boolean with default false { type: Boolean, default: false }
'email' Email with validation { type: String, required: true, match: emailRegex }
'password' Password with min length { type: String, required: true, minlength: 6 }
'url' URL with validation { type: String, match: urlRegex }
'userRef' Reference to User model { type: ObjectId, ref: 'User' }

Models

Create models with automatic features and enhancements:

JavaScript
// Create a model const User = mongoo.model('User', { firstName: 'string!', lastName: 'string!', email: 'email', birthDate: 'date?' }); // Get existing model const User = mongoo.getModel('User'); // Use predefined template const User = mongoo.model('User', mongoo.templates.user);

Auto-Features Included:

  • Timestamps: Automatic createdAt and updatedAt fields
  • Indexes: Auto-indexing for common fields
  • Virtuals: Automatic virtual fields (fullName, age, etc.)
  • Middleware: Auto-hooks for common operations
  • Validation: Smart validation with friendly messages

CRUD Operations

Complete CRUD operations with simplified syntax:

Create
Read
Update
Delete
JavaScript
// Create a single document const user = await mongoo.create('User', { name: 'Alice', email: 'alice@example.com', age: 28 }); // Create multiple documents const users = await User.create([ { name: 'Bob', email: 'bob@example.com' }, { name: 'Charlie', email: 'charlie@example.com' } ]); // Find or create const user = await mongoo.findOrCreate('User', { email: 'alice@example.com' }, { name: 'Alice', age: 28 } );
JavaScript
// Find all documents const users = await mongoo.find('User'); // Find with filter const activeUsers = await mongoo.find('User', { isActive: true, age: { $gte: 18 } }); // Find one document const user = await mongoo.findOne('User', { email: 'alice@example.com' }); // Find by ID const user = await mongoo.findById('User', '507f1f77bcf86cd799439011'); // Find with options const users = await mongoo.find('User', {}, { sort: { createdAt: -1 }, limit: 10, select: 'name email', populate: 'posts' });
JavaScript
// Update multiple documents await mongoo.update('User', { isActive: false }, { status: 'inactive' } ); // Update by ID const updatedUser = await mongoo.updateById( 'User', '507f1f77bcf86cd799439011', { age: 29, lastLogin: new Date() } ); // Save (create or update) const user = await mongoo.save('User', { _id: '507f1f77bcf86cd799439011', // If provided, updates existing name: 'Alice Updated', email: 'alice.updated@example.com' });
JavaScript
// Delete multiple documents await mongoo.delete('User', { isActive: false }); // Delete by ID await mongoo.deleteById('User', '507f1f77bcf86cd799439011'); // Check if document exists const exists = await mongoo.exists('User', { email: 'alice@example.com' }); // Count documents const count = await mongoo.count('User', { isActive: true });

Virtual Fields NEW

Virtual fields are computed properties that don't get stored in MongoDB:

JavaScript
// Auto virtuals (already included) // - fullName (if firstName and lastName exist) // - age (if birthDate exists) // - createdAtFormatted // Custom virtual field mongoo.virtual('User', 'profileUrl', function() { return `/users/${this.slug || this._id}`; }); // Virtual with setter mongoo.virtual('User', 'fullName', // Getter function() { return `${this.firstName} ${this.lastName}`; }, // Setter function(value) { const parts = value.split(' '); this.firstName = parts[0]; this.lastName = parts.slice(1).join(' '); } ); // Usage const user = await mongoo.findById('User', '...'); console.log(user.fullName); // Computed property console.log(user.profileUrl); // Custom virtual

Methods & Statics

Add custom instance methods and static methods to your models:

Instance Methods
Static Methods
Query Helpers
JavaScript
// Add instance method mongoo.method('User', 'getProfile', function() { return { name: this.name, email: this.email, memberSince: this.createdAt, profileUrl: `/users/${this._id}` }; }); // Instance method with async operations mongoo.method('User', 'deactivate', async function(reason) { this.isActive = false; this.deactivationReason = reason; this.deactivatedAt = new Date(); return await this.save(); }); // Usage const user = await mongoo.findById('User', '...'); const profile = user.getProfile(); await user.deactivate('User requested');
JavaScript
// Add static method mongoo.static('User', 'findByEmail', async function(email) { return await this.findOne({ email }).populate('posts'); }); // Static method with complex logic mongoo.static('User', 'getActiveStats', async function() { const stats = await this.aggregate([ { $match: { isActive: true } }, { $group: { _id: null, total: { $sum: 1 }, avgAge: { $avg: '$age' }, maxAge: { $max: '$age' }, minAge: { $min: '$age' } }} ]); return stats[0] || {}; }); // Usage const user = await mongoo.getModel('User').findByEmail('alice@example.com'); const stats = await mongoo.getModel('User').getActiveStats();
JavaScript
// Add query helper mongoo.query('User', 'byAgeRange', function(min, max) { return this.where('age').gte(min).lte(max); }); // Query helper for text search mongoo.query('User', 'search', function(text) { return this.find({ $or: [ { name: { $regex: text, $options: 'i' } }, { email: { $regex: text, $options: 'i' } } ] }); }); // Usage const adults = await mongoo.find('User').byAgeRange(18, 65); const searchResults = await mongoo.find('User').search('alice');

Middleware (Hooks)

Middleware (hooks) allow you to execute functions before or after certain operations:

Pre Hooks
Post Hooks
Aggregate Hooks
JavaScript
// Pre-save hook mongoo.pre('User', 'save', async function(next) { if (this.isModified('password')) { this.password = await bcrypt.hash(this.password, 12); } next(); }); // Pre-remove hook mongoo.pre('User', 'remove', async function(next) { // Remove user's posts when user is deleted await mongoo.delete('Post', { author: this._id }); next(); }); // Pre-find hook mongoo.pre('User', 'find', function(next) { // Only find active users by default this.where({ isActive: true }); next(); });
JavaScript
// Post-save hook mongoo.post('User', 'save', function(doc) { console.log(`User ${doc.name} was saved`); }); // Post-remove hook mongoo.post('User', 'remove', function(doc) { console.log(`User ${doc.name} was removed`); }); // Post-find hook mongoo.post('User', 'find', function(docs) { console.log(`Found ${docs.length} users`); });
JavaScript
// Pre-aggregate hook mongoo.pre('User', 'aggregate', function(next) { // Add match stage to exclude deleted users this.pipeline().unshift({ $match: { isActive: true } }); next(); }); // Post-aggregate hook mongoo.post('User', 'aggregate', function(docs) { console.log(`Aggregation returned ${docs.length} documents`); });

Transactions

Execute multiple operations as a single atomic transaction:

JavaScript
// Basic transaction await mongoo.withTransaction(async (session) => { // Create user const user = await mongoo.create('User', { name: 'Alice', email: 'alice@example.com' }, { session }); // Create user's first post await mongoo.create('Post', { title: 'First Post', content: 'Hello World!', author: user._id }, { session }); }); // Transaction with retry logic await mongoo.withRetryTransaction(async (session) => { // Transfer money between accounts await mongoo.update( 'Account', { _id: 'fromAccountId', balance: { $gte: 100 } }, { $inc: { balance: -100 } }, { session } ); await mongoo.update( 'Account', { _id: 'toAccountId' }, { $inc: { balance: 100 } }, { session } ); }, 3); // Retry up to 3 times // Manual session management const session = await mongoo.startSession(); try { session.startTransaction(); // Your operations here await mongoo.create('User', userData, { session }); await session.commitTransaction(); } catch (error) { await session.abortTransaction(); throw error; } finally { session.endSession(); }

Aggregation

Perform complex data analysis with MongoDB aggregation pipeline:

Basic Aggregation
Advanced Pipeline
Facets & Multiple
JavaScript
// Basic aggregation - group by category const categoryStats = await mongoo.aggregate('Product', [ { $group: { _id: '$category', totalProducts: { $sum: 1 }, avgPrice: { $avg: '$price' }, maxPrice: { $max: '$price' }, minPrice: { $min: '$price' } } }, { $sort: { totalProducts: -1 } } ]); // Lookup aggregation (join collections) const userOrders = await mongoo.aggregate('Order', [ { $lookup: { from: 'users', localField: 'customer', foreignField: '_id', as: 'customerInfo' } }, { $unwind: '$customerInfo' }, { $project: { orderNumber: 1, total: 1, customerName: '$customerInfo.name', customerEmail: '$customerInfo.email' } } ]);
JavaScript
// Advanced aggregation with multiple stages const salesReport = await mongoo.aggregate('Order', [ // Match orders from last 30 days { $match: { createdAt: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }, status: 'completed' } }, // Unwind items array { $unwind: '$items' }, // Lookup product details { $lookup: { from: 'products', localField: 'items.product', foreignField: '_id', as: 'productInfo' } }, // Unwind product info { $unwind: '$productInfo' }, // Group by product category { $group: { _id: '$productInfo.category', totalRevenue: { $sum: '$items.total' }, totalUnits: { $sum: '$items.quantity' }, avgOrderValue: { $avg: '$total' } } }, // Sort by revenue { $sort: { totalRevenue: -1 } } ]);
JavaScript
// Faceted search with multiple aggregations const facetedResults = await mongoo.aggregate('Product', [ { $match: { price: { $lte: 1000 }, isActive: true } }, { $facet: { // Price ranges priceRanges: [ { $bucket: { groupBy: '$price', boundaries: [0, 50, 100, 200, 500, 1000], default: 'Other', output: { count: { $sum: 1 }, products: { $push: '$name' } } } } ], // Categories categories: [ { $group: { _id: '$category', count: { $sum: 1 } } }, { $sort: { count: -1 } }, { $limit: 10 } ], // Total count totalCount: [ { $count: 'count' } ] } } ]);
New