MongoDB & Mongoose - A Refresher

 1. What is MongoDB?

  • MongoDB is a no SQL database, which stores Documents in Collections instead of Records in Tables as in SQL
  • It is used to store application data
  • Stored data doesn't enforce a specific data schema or any relations
  • MongoDB can also be easily connected to Node and Express, but we do not connect it directly to our front end (React)
  • MongoDB is a powerful database and it can be easily integrated into a node express environment

2. SQL vs NoSQL

  • NoSQL(e.g MongoDB) do not enforce a strict data schema(collections can contain documents with different schemas),  have less focus on relations, works with independent documents
  • SQL(e.g MySQL) enforce a strict data schema(define the tables and the corresponding records, normally don't deviate from that structure ), relations are a core feature the records are related

3. Connecting React to a Database?

  • Connecting react to the database is a bad idea
  • It is a highly insecure approach, secure authentication is not really possible if you directly connect your front end to a database, because to interact with the database, we need to provide credentials and we provide these credentials as part of our front end code, The problem is that our front end code is running in the browser and therefore anybody can access it so we would expose our credentials, this would also expose our full database so people could do more with a database than they're actually supposed to do
  • Therefore, we will connect react to our back end(node express). React will then send the requests to this back end and then the back end will process the information and establish the connection to the MongoDB server

4. Creating a Simple Backend & Connecting it to the Database

  • Create a node express app
  • Use MongoClient class in mongoDB SDK
  • Prepare url with password and database name for connecting to remote database

5. Creating a Document with MongoDB

  • Build client object of class MongoClient with prepared url
  • Create connection and then create database
  • Operate collection and document in the database

The code snipt of creating document:

const createProduct = async (req, res, next) => {
  const newProduct = {
    name: req.body.name,
    price: req.body.price,
  };

  // put the object into our MongoDB database
  const client = new MongoClient(url);
  try {
    await client.connect();
    const db = client.db(databaseName);
    await db.collection("products").insertOne(newProduct);
  } catch (error) {
    return res.json({ errorMessage: error });
  }
  client.close();
  res.json(newProduct);
  next();
};

6. Getting Data from the Database

  • Build a client
  • Build a connection
  • Refer to database and collection
  • Find the result

The code snipt of getting data:

const getProducts = async (req, res, next) => {
  const client = new MongoClient(url);
  let products;
  try {
    await client.connect();
    const db = client.db(databaseName);
    products = await db.collection("products").find().toArray();
  } catch (error) {
    return res.json({ errorMessage: error });
  }
  client.close();
  res.json(products);
};

7. Mongoose

  • Mongoose uses so called schemas which allow you to define the structure of the documents you want to store in your database
  • Schemas make storing and fetching data from the database a lot more convenient
  • Mongoose will allow us to connect to our database server and will also allow us to create and get data

8. Understanding Models & Schemas

  • Schema is blueprint of document data structure
  • Model created based on schema and will be exported to use
  • In mongoose.model function the first argument is name of the schema, this will also become the name of the collection without the capital starting character and in the plural form 

Models & Schemas example:

const mongoose = require("mongoose");

// schema is the blueprint for a document
const productSchema = new mongoose.Schema({
  name: { type: String, required: true },
  price: { type: Number, required: true },
});

// The model function
module.exports = mongoose.model("Product", productSchema);

9. Creating a Product

  • Create a product object based on the model abey to the schema
  • The object will insert into collection of database as document

Product object:

const mongoose = require("mongoose");

const productSchema = new mongoose.Schema({
  name: { type: String, required: true },
  price: { type: Number, required: true },
});

const Product = mongoose.model("Product", productSchema);

const createdProduct = new Product({
  name: req.body.name,
  price: req.body.price,
});

10. Connecting to the Database & Saving the Product

  • Mongoose uses a concept called connection pooling, it opens some connections and manages them actively to make sure we can always have a very efficient connection between our database and the backend
  • Mongoose connect method returns a promise so we can also add then to get result and catch to catch any potential errors
  • For creating and storing the document to the database we have to use the save method of the document module we've created based on schema. Save method will return a result refers to the newly created document that we just stored in our database
  • Save method refers to the right database specified in our url credentials,  it refers to the right collection which is named based on the first argument in our model method (the collection name will lowercase first letter, in plural form )

Connecting database and saving document with mongoose:

mongoose
  .connect(process.env.DB_URL_DBNAME)
  .then((result) => {
    console.log("Connected to database succesfully!");
  })
  .catch((error) => {
    console.log("Connection failed:", error);
  });

const createProduct = async (req, res, next) => {
  const createdProduct = new Product({
    name: req.body.name,
    price: req.body.price,
  });
  try {
    const result = await createdProduct.save();
    res.json(result);
  } catch (error) {
    console.log("Document inserting error:", error);
  }
};

11. Getting Products

  • We want to get product stored in our products collection, we know that all those products were created based on instances of the product model
  • So we can use some static methods on the model class (In the case, the find method), find is a  static method used directly on product module class
  • Find method related to Mongoose returns an array

Get docuemnts of collection in mongoose:

const getProducts = async (req, res, next) => {
  try {
    const products = await Product.find().exec();
    res.json(products);
  } catch (error) {
    console.log("Document getting error:", error);
  }
};

12. Understanding the ObjectID

  • ID added to the document each time we store a new document in the database
  • This is a unique ID for each document
  • ID we can identify a specific document and it gets added automatically no matter if we use the MongoDB driver or mongoose

13. Source code

Comments

Popular posts from this blog

WSL2配置proxychains, 使得终端走宿主机代理

Javascript Currying

Node.js & Express.js - A Refresher

What is MERN?