Skip to main content

Lab-2-6

(2% of the course mark)

MongoDB interaction with mongodb / moogoose Lab

  • In this lab, students will build a simple Node.js application that connects to a MongoDB database using the mongodb and moogoose packages. They will perform CRUD (Create, Read, Update, Delete) operations, manage connections efficiently, and handle errors properly. The lab focuses on practical database interaction within a backend application. MongoDB Compass is used to set up the MongoDB db.

Lab objectives

  • Set up and configure a MongoDB database for a Node.js application.

  • Use the mongodb and moogoose packages to establish a connection and execute queries.

  • Perform CRUD operations on a NoSQL database from a Node.js app.

  • Handle query results and potential errors effectively.

  • Understand how Object-Document Mapper (ODM) works.

  • Learn how to use MongoDB Compass in setting up a MongoDB db.

Initialize MongoDB db

  1. Open Docker Desktop and start mongodb-container.

  2. Open MongoDB Compass and create a new connection by clicking on the + plus icon.

  3. Set the Name to mongodb-container.

  4. Expand the Advanced Connection Options.

  5. On the General tab, set the following values:

    • Set the Connection String Scheme as mongodb

    • Set the Host as localhost:27017.

  6. Click on the Authentication tab and set the following values:

    • Set the Username as root

    • Set the Password as password.

  7. Click on Save & Connect.

  8. On the mongodb-container connection, create a Database by clicking on the + plus icon.

    • Set the Database Name as backend_db

    • Set the Collection Name as users.

  9. Download the users.json file to your computer.

  10. Import users.json to the users collection.

Database Objects

Ensure that all the database objects are created successfully before proceeding to the next step.

Create basic MongoDB Node.js app

  1. Open VSCode and create a folder named MongoDB-Node-App.

  2. Open the terminal and change the directory to MongoDB-Node-App.

  3. Initialize the app by running the following command:

npm init -y
  1. Install typescript by running the following commands:
npm install typescript -D
npm install @types/node -D
  1. Initialize tsconfig.json by running the following command:
npx tsc --init
  1. Modify tsconfig.json and uncomment outDir.

  2. Modify tsconfig.json and add the following property:

"removeComments": true
  1. Install nodemon by running the following command:
npm install nodemon -D
  1. Install dotenv by running the following command:
npm install dotenv
  1. Create an .env file in the root of your project and enter the following.
MONGO_URL_SCHEME=mongodb://
MONGO_USER=root
MONGO_PASSWORD=password
MONGO_HOST=localhost
MONGO_PORT=27017
MONGO_DB_NAME=backend_db
  1. Install mongodb by running the following command:
npm install mongodb
  1. Configure package.json by adding a new entry to the scripts property.
"build": "tsc",
"start": "nodemon ./dist/index",
  1. Configure package.json by adding a new property.
"type": "module"
  1. Create a file named index.ts and add the following code:
// Developer:
// Purpose:

import * as dotenv from "dotenv";
dotenv.config();
import { MongoDB } from "./lib/MongoDB";

async function main() {
const collectionName = "users";
console.time("Benchmark");
const mongoDB: MongoDB = new MongoDB();
const connectResponse = await mongoDB.connect();
console.log(connectResponse);
if (connectResponse.isConnected) {
let users: any = null;

console.log("===========================");
console.log("= Select all documents... =");
console.log("===========================");

users = await mongoDB.find(collectionName, {});
console.log(users);

console.log("==========================");
console.log("= Select one document... =");
console.log("==========================");

users = await mongoDB.find(collectionName, { userName: "elon.musk" });
console.log(users);

console.log("==========================");
console.log("= Insert one document... =");
console.log("==========================");

const insertResponse = await mongoDB.insert(collectionName, {
userName: "steve.jobs",
email: "steve.jobs@apple.com",
createdAt: new Date(),
});
console.log(insertResponse);
users = await mongoDB.find(collectionName, {});
console.log(users);

console.log("======================");
console.log("= Update document... =");
console.log("======================");

const updateResponse = await mongoDB.update(
collectionName,
{ userName: "steve.jobs" },
{
$set: { userName: "steve.balmer", email: "steve.balmer@microsoft.com" },
}
);
console.log(updateResponse);
users = await mongoDB.find(collectionName, {});
console.log(users);

console.log("======================");
console.log("= Delete document... =");
console.log("======================");

const deleteResponse = await mongoDB.delete(collectionName, {
userName: "steve.balmer",
});
console.log(deleteResponse);
users = await mongoDB.find(collectionName, {});
console.log(users);

const disConnectResponse = await mongoDB.disConnect();
console.log(disConnectResponse);
}

console.timeEnd("Benchmark");
}

main();
  1. In the root folder of the app, create a folder named lib.

  2. In the lib folder, create a file named DBConnectionFields.ts and add the following code:

// Developer:
// Purpose:

export interface DBConnectionFields {
userName: string;
password: string;
url: string;
urlScheme: string;
db: string;
}
  1. In the lib folder, create a file named MongoDB.ts and add the following code:
// Developer:
// Purpose:

import { MongoClient, Collection } from "mongodb";
import { DBConnectionFields } from "./DBConnectionFields.js";

export class MongoDB {
dbConnectionFields: DBConnectionFields;
mongoClient: MongoClient;

constructor() {
this.dbConnectionFields = {
userName: String(process.env.MONGO_USER),
password: String(process.env.MONGO_PASSWORD),
url: `${String(process.env.MONGO_HOST)}:${String(
process.env.MONGO_PORT
)}`,
urlScheme: String(process.env.MONGO_URL_SCHEME),
db: String(process.env.MONGO_DB_NAME),
};

this.mongoClient = new MongoClient(
`${this.dbConnectionFields.urlScheme}${this.dbConnectionFields.userName}:${this.dbConnectionFields.password}@${this.dbConnectionFields.url}`
);
}

async connect() {
const connectResponse = { isConnected: false, message: "" };
try {
await this.mongoClient.connect();
connectResponse.isConnected = true;
connectResponse.message = `Connected to: ${this.dbConnectionFields.url}.`;
} catch (error: any) {
connectResponse.message = `Could not connect to: ${this.dbConnectionFields.url}.`;
} finally {
return connectResponse;
}
}

async find(collectionName: string, options: any) {
const db = this.mongoClient.db(this.dbConnectionFields.db);
const collection: Collection = db.collection(collectionName);
let findResponse: any = null;
findResponse = collection.find(options);
const findResponseArray = await findResponse.toArray();
return findResponseArray;
}

async insert(collectionName: string, options: any) {
const db = this.mongoClient.db(this.dbConnectionFields.db);
const collection: Collection = db.collection(collectionName);
let insertOneResponse: any = null;
insertOneResponse = await collection.insertOne(options);
return insertOneResponse;
}

async update(documentName: string, key: any, value: any) {
const db = this.mongoClient.db(this.dbConnectionFields.db);
const collection: Collection = db.collection(documentName);
let updateOneResponse: any = null;
updateOneResponse = await collection.updateMany(key, value);
return updateOneResponse;
}

async delete(collectionName: string, options: any) {
const db = this.mongoClient.db(this.dbConnectionFields.db);
const collection: Collection = db.collection(collectionName);
let deleteManyResponse: any = null;
deleteManyResponse = await collection.deleteMany(options);
return deleteManyResponse;
}

async disConnect() {
const disConnectResponse = {
isDisconnected: false,
message: "",
};

try {
await this.mongoClient.close();
disConnectResponse.isDisconnected = true;
disConnectResponse.message = `Disconnected to: ${this.dbConnectionFields.url}.`;
} catch (error: any) {
disConnectResponse.message = `Could not disconnect to: ${this.dbConnectionFields.url}.`;
} finally {
return disConnectResponse;
}
}
}
  1. Build the app by running the following command:
npm run build
  1. Start the app by running the following command:
npm run start
  1. On the terminal output, take note of the value of Benchmark: xx.xxxms for this app, as it will be used later to compare with the result of the Mongoose-Node-App run. Save the screenshot as mongodb-node-app.png.

Implement Lab-2-3 Library app (MongoDB Database and Collection)

  1. Using the MongoDB Compass app, create a database named library_db, then select any of the tables used from the Lab-2-3 Library app and convert it into a collection.

  2. Create a sample data JSON file for the collection you previously created and import it into the library_db database via MongoDB Compass. Essentially, you will convert the table's values into JSON format.

Implement Lab-2-3 Library app (MongoDB-Node-App)

  1. Modify the .env file of the MongoDB-Node-App and update the value of MONGO_DB_NAME to library_db.
MONGO_DB_NAME=library_db
  1. Modify index.ts of the MongoDB-Node-App and write code that uses the following operations:

    • Find documents

    • Find a document

    • Insert a document

    • Update a document

    • Delete a document

  2. Build and run the modified app and take a screenshot of the terminal output and save it as library-mongodb-node-app.png.

Create basic Mongoose Node.js app

Drop MongoDB Database
  • Open the MongoDB Compass app, connect to mongodb-container, and drop the backend_db database by clicking the trash icon. Type backend_db to confirm the action, then click Drop Database.

  • The Mongoose Node.js app below will recreate the backend_db database and users collection on startup.

  1. Open VSCode and create a folder named Mongoose-Node-App.

  2. Open the terminal and change the directory to Mongoose-Node-App.

  3. Initialize the app by running the following command:

npm init -y
  1. Install typescript by running the following commands:
npm install typescript -D
npm install @types/node -D
  1. Initialize tsconfig.json by running the following command:
npx tsc --init
  1. Modify tsconfig.json and uncomment outDir.

  2. Modify tsconfig.json and add the following property:

"removeComments": true
  1. Install nodemon by running the following command:
npm install nodemon -D
  1. Install dotenv by running the following command:
npm install dotenv
  1. Create an .env file in the root of your project and enter the following.
MONGO_URL_SCHEME=mongodb://
MONGO_USER=root
MONGO_PASSWORD=password
MONGO_HOST=localhost
MONGO_PORT=27017
MONGO_DB_NAME=backend_db
MONGO_AUTH_SOURCE=authSource=admin
  1. Install mongoose by running the following commands:
npm install mongoose
  1. Configure package.json by adding a new entry to the scripts property.
"build": "tsc",
"start": "nodemon ./dist/index",
  1. Configure package.json by adding a new property.
"type": "module"
  1. Create a file named index.ts and add the following code:
// Developer:
// Purpose:

import * as dotenv from "dotenv";
dotenv.config();
import mongoose from "mongoose";
import { Schema } from "mongoose";

async function main() {
console.time("Benchmark");
const connectionString: string = `${process.env.MONGO_URL_SCHEME}${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@${process.env.MONGO_HOST}:${process.env.MONGO_PORT}/${process.env.MONGO_DB_NAME}?${process.env.MONGO_AUTH_SOURCE}`;
const mongoUrl: string = `${process.env.MONGO_URL_SCHEME}${process.env.MONGO_HOST}:${process.env.MONGO_PORT}/${process.env.MONGO_DB_NAME}`;

try {
await mongoose.connect(connectionString);

console.log(`Connected to: ${mongoUrl}.`);

// Create users schema
const userSchema = new Schema({
userName: String,
email: String,
createAt: Date,
});

const collectionName = "users";
const userModel = mongoose.model(collectionName, userSchema);

let tempUser;
// Populate the users collection
tempUser = await userModel.create({
userName: "bill.gates",
email: "bill.gates@microsoft.com",
createdAt: new Date(),
});

await tempUser.save();

tempUser = await userModel.create({
userName: "elon.musk",
email: "elon.musk@tesla.com",
createdAt: new Date(),
});

await tempUser.save();

let users: any = null;

console.log("===========================");
console.log("= Select all documents... =");
console.log("===========================");

users = await userModel.find();
console.log(users);

console.log("==========================");
console.log("= Select one document... =");
console.log("==========================");

users = await userModel.find({ userName: "elon.musk" });
console.log(users);

console.log("==========================");
console.log("= Insert one document... =");
console.log("==========================");

const newUser = await userModel.create({
userName: "steve.jobs",
email: "steve.jobs@apple.com",
createdAt: new Date(),
});

const saveResponse = await newUser.save();
console.log(saveResponse);
users = await userModel.find();
console.log(users);

console.log("======================");
console.log("= Update document... =");
console.log("======================");

const updateManyResponse = await userModel.updateMany(
{ userName: `steve.jobs` },
{
userName: "steve.balmer",
email: "steve.balmer@microsoft.com",
}
);

console.log(updateManyResponse);
users = await userModel.find();
console.log(users);

console.log("======================");
console.log("= Delete document... =");
console.log("======================");

const deleteManyResponse = await userModel.deleteMany({
userName: "steve.balmer",
});
console.log(deleteManyResponse);
users = await userModel.find();
console.log(users);
} catch (error: any) {
console.log(`Could not connect to: ${mongoUrl}.`);
} finally {
try {
mongoose.connection.close();
console.log(`Disconnected to: ${mongoUrl}.`);
} catch (error: any) {
console.log(`Could not disconnect to: ${mongoUrl}.`);
}

console.timeEnd("Benchmark");
}
}

main();
  1. Build the app by running the following command:
npm run build
  1. Start the app by running the following command:
npm run start
  1. On the terminal output, take note of the value of Benchmark: xx.xxxms for this app, as it will be used later to compare with the result of the MongoDB-Node-App run. Save the screenshot as mongoose-node-app.png.

Implement Lab-2-3 Library app (Mongoose-Node-App)

Drop MongoDB Database
  • Open the MongoDB Compass app, connect to mongodb-container, and drop the library_db database by clicking the trash icon. Type library_db to confirm the action, then click Drop Database.

  • The Mongoose Node.js app below will recreate the library_db database and the collection on startup.

  1. Modify the .env file of the Mongoose-Node-App and update the value of MONGO_DB_NAME to library_db.
MONGO_DB_NAME=library_db
  1. Modify index.ts of the Mongoose-Node-App and write code that uses the following operations:

    • Populate the collection with sample data

    • Find documents

    • Find a document

    • Insert a document

    • Update a document

    • Delete a document

  2. Build and run the modified app and take a screenshot of the terminal output and save it as library-mongoose-node-app.png.

Submission

  1. Create a folder named submit.
Delete node_modules

Delete the node_modules folder on any app that you are submitting.

  1. Copy the MongoDB-Node-App and Mongoose-Node-App folder and all the screenshots (mongodb-node-app.png, library-mongodb-node-app.png, mongoose-node-app.png, and library-mongoose-node-app.png) to the submit folder.

  2. Compare the benchmark values of the screenshots: library-mongodb-node-app.png and library-mongoose-node-app.png. and write your conclusion in the Comments text area.

  3. Write the answers to Step 23 of the Create a Basic Sequelize Node.js App section of the lab in the Comments text area.

  4. Create a zip file of the submit folder.

  5. Navigate back to where the lab was originally downloaded, there should be a Submissions section (see below) where the zip file can be uploaded.

submission