Mongoose 資料操作 三步驟從 MongoDB 到 API

me
林彥成
2019-09-07 | 2 min.
文章目錄
  1. 1. Mongoose 觀念與名詞
    1. 1.1. 什麼是 ODM/ORM?
  2. 2. 三步驟從資料庫到 API
    1. 2.1. Mongo DB 資料庫設定
    2. 2.2. Mongoose Schema 設計
    3. 2.3. Mongoose ODM 資料操作
  3. 3. Mongoose 專案架構

Mongoose 是讓開發者透過 ODM (Object Data Model) 的概念來連接並操作 MongoDB 的一套工具,透過 npm 就能夠下載安裝使用。

網站有分成前跟後端,而 Mongoose 也可以看成是 MongoDB 的前端介面。

Mongoose 觀念與名詞

Mongoose 提供了 schema-based 的解決方案讓我們直接操作資料,在透過 Mongoose 操作資料庫時,有幾個名詞要先有概念:

  1. Schema: 存資料庫模型的檔案
  2. Model: 由 Schema 當參數產生的 instance 可以用來操作資料庫
  3. collection: 在 MongoDB 中的表

什麼是 ODM/ORM?

由於 Express 這類框架無法操作資料庫,所以將資料表示為 JavaScript 的 Object,再透過 ODM/ORM 工具定義的 data schema 去操作資料庫,透過 Mongoose 就可以達到操作資料庫的目的,ODM/ORM 通常可以降低開發及維護成本,因此一般情況下都推薦使用。

  • ODM: Object Data Model,對應 NoSQL Database
  • ORM: Object Relational Model,對應 SQL-Bsaed Database

三步驟從資料庫到 API

  1. Mongo DB 資料庫設定
  2. Mongoose Schema 設計
  3. Mongoose ODM 資料操作

Mongo DB 資料庫設定

最常用的就是運用 Mongoose 搭配 Mongo DB:

  1. 在安裝完 Mongo 後,進入 shell 去連線看看 mongo --port 27017
  2. 成功連線後可以選擇資料庫開始下指令,像是 use test
  3. 進入 test 中設定使用者及權限:
1
2
3
4
5
6
db.dropAllUsers();
db.createUser({
user: "test",
pwd: "test",
roles: [{ role: "readWrite", db: "test" }],
});
  1. 資料庫為了安全起見會要將資料庫的 authorization 打開,windos 請參考連結,ubuntu 請去編輯 etc 資料夾底下的 Mongo 設定,加入設定如下:
1
2
security:
authorization: enabled

Mongoose Schema 設計

要使用 Mongoose 操作的第一步就是要從定義 Schema 開始,定義完成後 Schema 會自動對應到 MongoDB 中的一個 collection,另外因為不像傳統資料庫那樣有 join 的概念,所以拿資料的時候可以依照我們的使用情境去設計,像是以撈取為主的話就可以透過雙向參照的設計去加速,詳細可以參考MongoDB Schema 設計指南,分類有以下幾種:

  • Modeling One-to-Few 少量級關聯模式 (Embedding)
  • One-to-Many 多量級關聯模式 (Child-Referencing)
  • One-to-Squillions 海量級關聯模式 (Parent-Referencing)
  • Two-Way Referencing (雙向參照設計)
  • 多對一反正規化 (Denormalizing from Many -> One)

Mongoose ODM 資料操作

Mongoose 則是協助我們在 node.js 專案中操作 Mongo DB,在程式中定義好 schema (不需要開欄位),確認資料庫連線沒有問題就可以直接開始操作了。

比較大的問題是 node.js 不像 C#.net 那樣的語言有工具可以自動產生程式碼和架構,所以這個部分就是看每個人的狀況去放置,但還是以關注點分離的概念為主:

  1. 建立跟 MongoDB 的連線
1
2
3
4
5
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/test", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
  1. 在 model 中定義 Schema 並創造一個 model
1
2
3
4
5
6
7
8
9
/**
* user model
*/

const userSchema = mongoose.Schema({
id: String,
});

module.exports = mongoose.model("user", userSchema);
  1. 使用剛剛產生的 model instance 在 controller 中撈資料
1
2
3
4
5
6
7
8
9
10
11
12
/**
* user controller
*/

const getUser = (id) => {
return new Promise((resolve, reject) => {
const User = require("./model");
User.findOne({ id }).exec((error, docs) => {
resolve(docs);
});
});
};
  1. 透過 route 開 API 給前端使用
1
2
3
4
5
6
const express = require("express");
const app = express();
app.get("/api/v1/user", (req, res) => {
const user = getUser("defaultID");
res.json(user);
});

Mongoose 專案架構

通常 Mongoose 會搭配一個後端的框架來做使用,像是 Express 或是 Koa 等等,那在網路上有看到常見的兩種架構。

  1. 第一種是依照資料表去做區分,把同個資料表的 model、controller、route 集中存放,覺得較適合大型專案。
1
2
3
4
5
6
7
8
9
10
11
├── src/
│ ├── entities/ # 按照資料表去區分
│ │ └── user/ # 使用者表
│ │ ├── model.js # Schema 定義
│ │ ├── controller.js # 資料庫 CRUD
│ │ └── route.js # API 設定
│ └── index.js # 入口
├── .eslintrc # ESLint 設定檔
├── package-lock.json
├── package.json
└── README.md
  1. 第二種則是依照功能性,controller、routes、models 集中放置在各自的分類資料夾,覺得較適合小型專案。
1
2
3
4
5
6
7
8
9
├── src/
│ ├── controller/ # 資料庫 CRUD
│ ├── routes/ # API 設定
│ ├── models/ # Schema 定義
│ └── index.js # 程式入口
├── .eslintrc # ESLint 設定檔
├── package-lock.json
├── package.json
└── README.md

喜歡這篇文章,請幫忙拍拍手喔 🤣


share