Databases & NoSQL

Unlocking MongoDB and Mongoose: Your Comprehensive Guide to NoSQL Databases, Scalability, and Advanced Features

By the Domain India teamPublished 9 min read
Knowledge base article
Contents (9 sections)

MongoDB is a document database: instead of rows in fixed tables, it stores flexible, JSON-like documents. Mongoose is the Node.js library most developers use on top of it, adding schemas, validation and a friendlier API. This guide explains how MongoDB works, when to choose it over a relational database, the essential queries, and how to use Mongoose safely in a Node.js app.

Key takeaways

MongoDB stores data as BSON documents in collections, with flexible schemas, built-in replication and horizontal scaling. Use it when your data is naturally nested and varies from record to record; for most business apps, PostgreSQL or MySQL is still the safer default. In Node.js, connect with Mongoose using async/await, define schemas with validation, and never expose MongoDB to the internet without authentication. MongoDB is not available from Domain India shared hosting; run it on a VPS.

1. What MongoDB is

A MongoDB database holds collections, and each collection holds documents. A document is a set of fields, and a field can hold text, numbers, dates, arrays or other documents:

json
{
  "_id": "665f1c2e9b1e8a3d4c5b6a7f",
  "name": "Asha Rao",
  "email": "[email protected]",
  "addresses": [
    { "type": "billing", "city": "Chennai", "pin": "600001" }
  ],
  "createdAt": "2026-09-23T10:15:00Z"
}

MongoDB stores documents as BSON, a binary form of JSON that adds types JSON lacks, such as dates, 64-bit integers, decimals and binary data. Every document gets a unique _id.

Its main strengths:

  • Flexible schema: documents in one collection don't need identical fields.
  • Rich queries and indexes, including compound, text and geospatial indexes.
  • Aggregation pipeline for reports and transformations inside the database.
  • Replica sets for high availability, and sharding to spread data across servers.
  • Multi-document transactions on replica sets, when you need them.

2. MongoDB or a relational database?

QuestionMongoDBPostgreSQL or MySQL
Data shapeNested, varies per recordTables with clear relationships
SchemaFlexible; enforce it in your app or with validationDefined in the database
Relationships and joinsPossible ($lookup), but not its strengthCore strength
TransactionsSupported; design to need them rarelyStandard for everything
ScalingBuilt-in sharding across serversUsually scale up, then replicas
Good fitsCatalogues, content, event logs, IoT dataBilling, orders, accounting, most business apps

Both are fast, reliable and mature. Pick MongoDB when documents really are the natural shape of your data, not only to avoid designing a schema. PostgreSQL's JSONB column covers many "flexible data" needs inside a relational database. For a fuller comparison, see Choosing between PostgreSQL, MySQL, SQLite and MongoDB.

3. Tools you will use

  • mongosh: the MongoDB Shell, for queries and admin work from a terminal. It replaced the old mongo shell, which was removed in MongoDB 6.0.
  • MongoDB Compass: the official desktop app for browsing data, building queries and checking indexes.
  • Official drivers for Node.js, Python, PHP, Java and other languages.

Robo 3T, which many older guides recommend, is no longer maintained. Use Compass instead.

4. Essential queries

These work in mongosh and, with small changes, in the Node.js driver.

javascript
// Create
db.users.insertOne({ name: "Asha", email: "[email protected]", active: true });
db.users.insertMany([{ name: "Ravi" }, { name: "Meena" }]);

// Read
db.users.find({ active: true }).sort({ name: 1 }).limit(20);
db.users.findOne({ email: "[email protected]" });

// Update
db.users.updateOne({ email: "[email protected]" }, { $set: { active: false } });
db.users.updateMany({ active: false }, { $set: { status: "archived" } });

// Delete
db.users.deleteOne({ email: "[email protected]" });

Indexes make queries fast. Create one for every field you filter or sort on often:

javascript
db.users.createIndex({ email: 1 }, { unique: true });
db.orders.createIndex({ customerId: 1, createdAt: -1 });

Aggregation runs multi-step reports inside the database:

javascript
db.orders.aggregate([
  { $match: { status: "paid" } },
  { $group: { _id: "$customerId", total: { $sum: "$amount" } } },
  { $sort: { total: -1 } }
]);

Use explain("executionStats") on a slow query to see whether it uses an index.

5. Mongoose: schemas and models

Mongoose is an Object Document Mapper (ODM) for Node.js. It adds a schema layer, validation, middleware and helpers on top of the MongoDB driver. Install it with npm install mongoose.

javascript
// db.js
import mongoose from 'mongoose';

await mongoose.connect(process.env.MONGODB_URI);

mongoose.connection.on('error', (err) => {
  console.error('MongoDB connection error:', err);
});

Keep the connection string in an environment variable, never in your code. Older guides pass useNewUrlParser and useUnifiedTopology; current Mongoose ignores them, so leave them out.

A schema with validation, and a model built from it:

javascript
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';

const userSchema = new mongoose.Schema(
  {
    name: { type: String, required: true, trim: true },
    email: { type: String, required: true, unique: true, lowercase: true },
    passwordHash: { type: String, required: true, select: false },
    role: { type: String, enum: ['customer', 'admin'], default: 'customer' }
  },
  { timestamps: true }
);

userSchema.pre('save', async function () {
  if (this.isModified('passwordHash')) {
    this.passwordHash = await bcrypt.hash(this.passwordHash, 12);
  }
});

export const User = mongoose.model('User', userSchema);

select: false keeps the password hash out of query results unless you ask for it, and timestamps adds createdAt and updatedAt.

6. CRUD with Mongoose

Mongoose uses promises; callbacks were removed in Mongoose 7, so use async/await:

javascript
const user = await User.create({ name: 'Asha', email: '[email protected]', passwordHash: 'secret' });

const found = await User.findById(user._id).lean();
const admins = await User.find({ role: 'admin' }).sort({ name: 1 }).limit(50);

await User.findByIdAndUpdate(user._id, { name: 'Asha Rao' }, { new: true, runValidators: true });

await User.findByIdAndDelete(user._id);

Two habits that matter:

  • Use .lean() for read-only queries. It returns plain objects and is much faster.
  • Pass runValidators: true on updates, because Mongoose does not validate update queries by default.

Population replaces a stored ID with the referenced document:

javascript
const postSchema = new mongoose.Schema({
  title: String,
  author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});
const Post = mongoose.model('Post', postSchema);

const posts = await Post.find().populate('author', 'name email');

Population runs extra queries, so for data you always read together, embedding it in one document is often better.

7. Security essentials

Never expose MongoDB without authentication

Automated scanners find MongoDB servers open on port 27017 within hours, then copy and delete the data for ransom. Turn on authorization, keep the server bound to 127.0.0.1 or a private network, and reach it remotely through an SSH tunnel or a firewall rule that allows only your app server.

  • Turn on access control with security.authorization: enabled in mongod.conf, and give each app its own user with access to its own database only.
  • Use TLS for any connection that leaves the server.
  • Never build queries from raw user input. An attacker can send { "$ne": null } instead of a password. Validate input types, and keep Mongoose's sanitizeFilter option in mind.
  • Back up with mongodump, and test a restore.

8. Scaling: replica sets and sharding

A replica set is a group of MongoDB servers holding the same data. One is the primary; the others copy it and take over automatically if it fails. Use at least three members in production. Replica sets also enable transactions and change streams.

Sharding splits a large collection across several replica sets using a shard key. It adds real complexity, so most apps never need it: add indexes, a bigger server and a replica set first.

9. Running MongoDB with Domain India

Where MongoDB works
  • A Domain India VPS, where you install and manage MongoDB yourself with full root access
  • Your Node.js app on the same VPS, connecting over 127.0.0.1
Where it doesn't
  • Shared hosting (cPanel, DirectAdmin, Webuzo): there is no MongoDB server, and you can't install one
  • Connecting from shared hosting to MongoDB Atlas: outgoing port 27017 is not allowed on our shared servers
  • Shared hosting runs Node.js apps with MySQL. MongoDB is not available from shared hosting, so use MySQL there, or move the app.
  • App Platform runs Node.js apps and includes a PostgreSQL database with every plan. It has no built-in MongoDB. If you plan to connect an app there to an external MongoDB service, test the connection from the app before you rely on it.
  • VPS is self-managed with full root access, so you can install MongoDB and keep it private. Follow Installing MongoDB on a Domain India VPS.
VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details
App Starter
₹100/mo + GST
  • 512 MB RAM per app
  • 1 vCPU
  • 5 GB NVMe SSD
  • PostgreSQL Database
See plan details
What is the difference between MongoDB and Mongoose?

MongoDB is the database server that stores documents. Mongoose is a Node.js library that connects to MongoDB and adds schemas, validation, middleware and model methods on top of the official driver.

Is MongoDB better than MySQL?

Neither is better in general. MongoDB suits nested, varied data such as catalogues and event logs. MySQL and PostgreSQL suit data with clear relationships, such as orders, invoices and accounts, which covers most business apps.

Can I use MongoDB on Domain India shared hosting?

No. Shared hosting has no MongoDB server, and outgoing connections to port 27017, which MongoDB Atlas uses, are not allowed from our shared servers. Use MySQL on shared hosting, or run MongoDB on a VPS.

Do I still need useNewUrlParser and useUnifiedTopology?

No. Current versions of Mongoose and the MongoDB Node.js driver ignore these options. Call mongoose.connect with just your connection string.

Does MongoDB support transactions?

Yes. MongoDB supports multi-document ACID transactions on replica sets and sharded clusters. Single-document writes are always atomic, so a good document design needs transactions only rarely.

How do I secure a MongoDB server?

Turn on authorization, create a separate user for each app, keep the server bound to 127.0.0.1 or a private network, use TLS for remote connections, and back up regularly with mongodump.

Ready to run MongoDB? Set it up on a Domain India VPS, or build your Node.js app on the App Platform with its included PostgreSQL database.

Run MongoDB on your own VPS

Full root access, so you can install MongoDB, keep it private and run your Node.js app beside it.

See VPS plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
MongoDB and Mongoose Guide for Node.js Developers