Node JS

Part 5 : MONGO THE DB

MONGO THE DB

  1. MongoDB Introduction
  2. MongoDB CMD
  3. MongoDB Optimization 
  4. MongoDB Transaction
  5. Mongoose JS
  6. Schemas & Models
  7. Middleware, methods & statics

1. MongoDB Introduction

What is Mongo DB?

MongoDB is a source-available cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas.

1. MongoDB Introduction

Key Features of MongoDB

  • Document-based storage: Stores data in BSON format (Binary JSON).

  • Flexible schema: No predefined schema is required.

  • Scalability: Horizontally scalable using sharding.

  • Rich querying: Supports complex queries and aggregation pipelines.

  • Indexing: Optimizes query performance with indexes.

1. MongoDB Introduction

MongoDB Components

  • Database: Contains collections.

  • Collection: Contains multiple documents.

  • Document: A JSON-like data structure.

{ 
 	"name": "Alice", 
    "age": 23 
}

2. MongoDB CMD

Start the mongodb server

> mongod

Opening mongodb's shell

> mongosh

Opening mongodb's shell from atlas url

> mongosh 'url'

2. MongoDB CMD

get the list of instruction that you can make

> help

show the list of dbs in the server

> show dbs

2. MongoDB CMD

Use/create  a new database

> use $Dbname

Show collections

> show collections

2. MongoDB CMD

DB methods

> db.help()

insert into/create collections

> db.collectionName.insert({
	//parameters
})

2. MongoDB CMD

insert into/create collections

db.cars.insertMany([
  { brand: "Ford", model: "Mustang", year: 2021, features: ["Cruise Control", "Navigation"] },
  { brand: "Tesla", model: "Model 3", year: 2023, features: ["Autopilot", "Electric"] },
]);
db.cars.insertOne({
  brand: "Toyota",
  model: "Corolla",
  year: 2020,
  features: ["Air Conditioning", "Bluetooth", "Backup Camera"],
});

2. MongoDB CMD

db.cars.find({}, { brand: 1, model: 1, _id: 0 });

Only show brand and model (Projection)

db.cars.find({ year: { $gte: 2020 } });

Find cars from 2020 or newer

find data

db.cars.find();

2. MongoDB CMD

update data

db.cars.updateOne({ model: "Corolla" }, { $set: { year: 2021 } });

update multiple data

db.cars.updateMany({ year: { $lt: 2020 } }, { $set: { status: "Outdated" } });

2. MongoDB CMD

Delete data

db.cars.deleteOne({ model: "Mustang" });

Delete multiple data ( year older than 2015)

db.cars.deleteMany({ year: { $lt: 2015 } });

2. MongoDB CMD

Exit mongodb shell

> exit

3. MongoDB Optimization

Indexing

Indexes are a crucial component in MongoDB that optimize query performance. They allow MongoDB to quickly locate data within a collection, reducing the need to scan every document (a collection scan) when executing a query.

3. MongoDB Optimization

Best Practices for Indexes

  • Index Only When Necessary

    • Indexes consume additional disk space and impact write performance since they need to be updated with every write operation.
  • Use Compound Indexes Wisely

    • Ensure the order of fields in a compound index matches the query's filter and sort pattern.
  • Monitor Index Usage

    • Use db.collection.stats() and the Index Usage Statistics to identify unused indexes.
  • Avoid Over-Indexing

    • Too many indexes can degrade write performance.
  • Analyze Query Performance

    • Use explain() to understand the impact of indexes on queries.

3. MongoDB Optimization

Indexing

Indexes improve query performance. Create indexes using `createIndex()`.

db.collection.createIndex({ fieldName: 1 });
db.students.createIndex({ name: 1 });

Create an index on `name` in the `students` collection:

3. MongoDB Optimization

Index order

When creating an index in MongoDB, you specify the sort order for the field(s) in the index as ascending (1) or descending (-1). This determines how the values in the indexed field are arranged within the index.

db.students.createIndex({ age: 1 });
db.students.find().sort({ age: 1 });

Ascending Order 

3. MongoDB Optimization

Index order

When creating an index in MongoDB, you specify the sort order for the field(s) in the index as ascending (1) or descending (-1). This determines how the values in the indexed field are arranged within the index.

db.students.find().sort({ name: -1 });
db.students.find().sort({ name: -1 });

Descending Order

3. MongoDB Optimization

Compond Index

Combines multiple fields into a single index to support queries that filter or sort by those fields.

db.students.createIndex({ name: 1, age: -1 });

Ascending `name`, descending `age`

3. MongoDB Optimization

Multikey Index

Supports indexing on array fields. Each array element is indexed separately.

db.articles.createIndex({ tags: 1 });

3. MongoDB Optimization

Other indexs

  • Text Index: Supports text search on string fields.
db.articles.createIndex({ description: "text" });
  • Hashed Index: Used for hashed sharding or equality matches on a field.
db.users.createIndex({ _id: "hashed" });
  • Wildcard Index: Indexes all fields in a document or specific nested fields dynamically.
db.products.createIndex({ "details.$**": 1 });

3. MongoDB Optimization

Index options

In MongoDB, index options allow you to configure how an index behaves when created. These options can enforce specific constraints, optimize query performance, and manage how data is stored in the index.

3. MongoDB Optimization

Index options

Option Description
unique Ensures values in the indexed field(s) are unique.
sparse Indexes only documents with the indexed field.
expireAfterSeconds Sets a TTL for documents.
partialFilterExpression Indexes only documents that satisfy a condition.
collation Configures locale-specific and case-insensitive comparisons.
background Builds the index without blocking operations.
name Custom name for the index.
default_language Specifies the language for text indexes.
weights Sets the importance of fields in a text index.
hidden Makes the index inactive for queries unless explicitly hinted.

3. MongoDB Optimization

Managing Indexes

  • View Existing Indexes
db.collection.getIndexes();
  • Drop an Index
db.collection.dropIndex("index_name");
  • Drop All Indexes
db.collection.dropIndexes();

4. MongoDB Transactions

A transaction in MongoDB is a sequence of one or more operations that are executed as a single unit. Transactions ensure atomicity, consistency, isolation, and durability (ACID properties). This means that either all operations in the transaction are applied successfully, or none are applied, maintaining the integrity of your data.

4. MongoDB Transactions

When to Use Transactions

  • Multiple documents or collections must be updated together.
  • Changes need to occur in a consistent manner (e.g., financial systems, inventory updates, etc.).
  • You want to prevent partial updates in the event of errors.

4. MongoDB Transactions

How to Use Transactions

  • Start a Session: To initiate a transaction, you need to start a session. A session allows MongoDB to group operations together.
const session = db.getMongo().startSession();
  • Start a Transaction: Use the startTransaction() method on the session object to begin the transaction.

session.startTransaction();
  • Perform Operations Within the Transaction: Any CRUD operations (insert, update, delete, etc.) that you want to be part of the transaction should use the session.

const accounts = session.getDatabase("bank").accounts;
accounts.updateOne({ accountNumber: 1 }, { $inc: { balance: -100 } }, { session });
accounts.updateOne({ accountNumber: 2 }, { $inc: { balance: 100 } }, { session });

4. MongoDB Transactions

How to Use Transactions

  • Commit the Transaction: After performing all operations successfully, commit the transaction to apply the changes.

session.commitTransaction();
  • Abort the Transaction: If any operation fails or an error occurs, abort the transaction to roll back all changes.

session.abortTransaction();
  • End the Session: After committing or aborting the transaction, close the session.

session.endSession();

5. Mongoose JS

Install mongoose JS

> npm i mongoose
const mongoose=require("mongoose");

require mongoose JS

mongoose.connect('mongodb://localhost:27017/DBName');

connect to the database

5. Mongoose JS

Handle mongoose connection

mongoose.connect('mongodb://localhost:27017/Demo')
	.then((connection) => {
		console.log("db connected");
	})
	.catch((reason) => {
		console.error(reason);
		process.exit(-1);
	});
mongoose.connect(URI,{ useNewUrlParser: true });

Use new URI parser

6. Schemas & Models

Create a schema

const mongoose =require( 'mongoose');
const { Schema } = mongoose;

const userSchema = new Schema({
	first_name:  String, // String is shorthand for {type: String}
	last_name: String,
	age:Number
});
const userModel=mongose.model("User",userSchema);

Create a model

6. Schemas & Models

Create a data

async function createData(first_name,last_name,age){
  try{
    const user = await userModel.create({first_name,last_name,age});
    return user;
  }catch(e){
    return null;
  } 
}

6. Schemas & Models

Find data

async function findData(first_name){
  try{
    const users = await userModel.find({first_name});
    return users;
  }catch(e){
    return [];
  } 
}

6. Schemas & Models

Find data

async function findData(first_name){
  try{
    const users = await userModel.find({first_name});
    return users;
  }catch(e){
    return [];
  } 
}

7. Middleware & methods

Action Middleware

userSchema.pre('save', function() {
  // do stuff
});
userSchema.post('save', function(docs) {
  // do stuff
});

before saving 

after saving

7. Middleware & methods

Action Middleware

Events

  • aggregate
  • bulkWrite
  • count
  • countDocuments
  • createCollection
  • deleteOne
  • deleteMany
  • estimatedDocumentCount
  • find
  • findOne
  • findOneAndDelete
  • findOneAndReplace
  • findOneAndUpdate
  • init
  • insertMany
  • replaceOne
  • save
  • update
  • updateOne
  • updateMany
  • validate

7. Middleware & methods

Instance Methods

userSchema.methods.findSimilarAge = function() {
    return mongoose.models['User'].find({ age: this.age });
  };
async function findSameAgeData(first_name){
  try{
    const user = await userModel.findOne({first_name});
    return user.findSimilarAge();
  }catch(e){
    return [];
  } 
}

7. Middleware & methods

Static method

userSchema.statics.findAdults = function() {
    return this.find({ age: {$gte : 19 } });
};
async function findAdultsData(){
  try{
    const adults = await userModel.findAdults();
    return adults;
  }catch(e){
    return [];
  } 
}

MONGO THE DB

Ends

Node js Chapter 5

By Youcef Madadi

Node js Chapter 5

  • 313