MIT Weblab笔记 - MongoDB

Introduction

Why Use Databse in Web Development?

  1. Store data persistently
  2. Fast read and write speed
  3. Concurrency issues
  4. Data security

Relational Database (SQL) and Document Database (NoSQL)

Databases are generally categorized into two types: Relational Databases (SQL) and Document Databases (NoSQL).

  • Relational Database: Store data in tables. e.g., MySQL, PostgreSQL.
  • Document Database: Store data as documents (like JSON objects). e.g. MongoDB

Interact with Database

  • Get

  • Post

MongoDB

Core Concepts

  • Database: A container for collections.
  • Collection: A group of MongoDB documents, akin to a table in SQL.
  • Document: A record in a collection, stored in Binary JSON format, allowing nested structures and arrays, like a row in a table.
  • Field: A key-value pair within a document.
  • ObjectId: The default primary key for a MongoDB document (_id field), automatically generated.

Connect to MongoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// server.js
const mongoose = require("mongoose"); // import mongoose

const mongoConnectionURL = "mongodb+srv://USERNAME:PASSWORD@DB.mongodb.net/test?retryWrites=true";
const databaseName = "someDatabaseName";
const options = {
useNewUrlParser: true,
useUnifiedTopology: true,
dbName: databaseName,
};

mongoose.connect(mongoConnectionURL, options)
.then(() => console.log("Connected."))
.catch((error) => console.log(`Error connecting to MongoDB: ${error}`));
  • mongoose: A NodeJS library that allows MongoDB integration

Schemas and Models

  • Schemas define the structure of your documents
  • Define the keys and types of the values corresponding to the keys
  • Schema Types: String, Number, Date, Buffer, Boolean, Mixed, ObjectId, Array
  • Models is responsible for creating and reading documents from the database

Example:

1
2
3
4
5
6
7
8
9
const mongoose = require("mongoose");

const StudentSchema = new mongoose.Schema({
name: String,
age: Number,
classes: [String], // the type of the elements inside an array should also be specified
});

module.exports = mongoose.model("ModelName", StudentSchema);
  • Usually Define one Schema and Model per file, and export the model

Find Document

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// In backend:
const Story = require("./models/story"); // import the model

const emptyQuery = {}; // empty query: return all documents
const query = { name: "Tim", age: 21 }; // return all documents with name Tim and age 21

router.get("/stories", (req, res) => {
Story.find(emptyQuery).then((allStories) => {
// return an array of documents
res.send(allStories);
})
});

router.get("/comment", (req, res) => {
Comment.find({ parent: req.query.parent }).then((comments) => {
res.send(comments);
});
});
  • find(query) returns an array.
  • findOne(query): returns only one document that matches the query.
  • someModel.find() retuens a promise, which is the finding result, and we can use .then() to handle it.

Save Document

1
2
3
4
5
6
7
8
9
10
11
12
// In backend:
const Comment = require("./models/comment");

router.post("/comment", (req, res) => {
const newComment = new Comment({
creator_name: myName,
parent: req.body.parent,
content: req.body.content,
});

newComment.save().then((comment) => res.send(comment));
});
  • We can create a new document by const newDocument = new ModelName({parameters}).
  • newDocument.save() returns a promise. This promise resolves to the document that was saved to the database.
  • Every document is automatically assigned a unique identifier, the identifier is assigned under the “_id” field. How to utilize “_id”?
    • At Frontend, get document get queries.
    • Backend calls find() and send the result to frontend.
    • Frontend retrieves and passes the “_id” of one object (one document in database) by
      1
      2
      3
      4
      5
      6
      7
      <Card
      key={`Card_${storyObj._id}`}
      // retrieve the _id from obj, which is the _id generated by MongoDB
      _id={storyObj._id}
      creator_name={storyObj.creator_name}
      content={storyObj.content}
      />
    • Pass the “_id” to the get query to retrieve related objects
      1
      2
      3
      get("/api/comment", { parent: props._id }).then((comments) => {
      setComments(comments);
      });

Delete Document

1
2
3
4
5
6
7
Student.deleteOne({ name: "Alice" })
.then(() => console.log("Deleted"))
.catch((error) => console.log(`Error: ${error}`));

Student.deleteMany({ name: "Alice" })
.then((student) => console.log("Deleted many documents"));
.catch((error) => console.log(`Error: ${error}`));

Update

1
2
3
4
5
Student.findOne(query) 
.then((student) => {
student.fieldToUpdate = newValue;
student.save()
});

MIT Weblab笔记 - MongoDB
https://thiefcat.github.io/2024/07/15/MIT-Weblab/mongoDB/
Author
小贼猫
Posted on
July 15, 2024
Licensed under