跳至主要内容

[mongodb] MongoDB — Mongoose 介紹與使用教學 (上)

參考資料:

MongoDB 前置作業(本地端)

本篇主要是介紹 Mongoose 的語法,所以在安裝的部分並不會太詳細的介紹。

如果要使用本地端進行測試的話,必須先安裝以下兩個由官方提供的應用程式,分別是:

另外也建議大家安裝 MongoDB Compass,它是由官網提供的圖形化桌面應用程式,我們可以直接在該應用程式看到所有儲存在資料庫的資料,並且可以針對資料進行新增修改刪除,在測試的過程中會比較方便。

Image

以上都安裝完以後,在 Terminal 輸入 mongosh,如果有成功連線代表安裝成功。

Image

MongoDB 前置作業(MongoDB Cloud)

而如果是使用 MongoDB Cloud(MongoDB Atlas)來進行開發的話,在建立完 Database 後,可以在後台的 Atlas 介面看到我們的 Cluster0,點擊 Connect。

Image

之後點擊 Connect your application

Image

我們只要先把 uri 那段複製起來就好,等等在初始化的部分需要使用到該 uri,記得在"password"的部分要改成自己的 MongoDB 密碼,密碼也要注意不要外洩,所以 uri 建議是儲存在.env。

Image

初始化

在開發的過程中也強烈建議大家使用 nodemon 來監聽自己的 node js 檔案,當檔案有異動時,nodemon 會幫你 restart server,才不用每次做一點更動之後就要重新執行 node js 的檔案。

這邊先執行以下指令來安裝 mongoose:

npm install mongoose

將套件安裝成功後,就來進行基本的連線設定吧,先建立一支新的檔案,名為 server.js,在 connect 的時候把 uri 填上,port 後面的斜線要填上你要建立的資料庫名稱,當我們對資料庫進行操作時才會建立該資料庫。

server.js
const mongoose = require("mongoose");//如果是使用cloud的話 第一個參數就要放cloud給予的uri位置,在<password>的部分要改成自己的MongoDB密碼,才能成功連線。//本地端預設: mongodb://127.0.0.1:27017/你要建立的資料庫名稱//cloud:mongodb+srv://Wei:<password>@cluster0.adryn.mongodb.net/?retryWrites=true&w=majoritymongoose.connect("mongodb://127.0.0.1:27017/testdb", () => {  console.log("connected");});

之後打開 Terminal,輸入以下指令:

nodemon ./server.js

要是連線成功的話就會在 Terminal 看到 connected。

Image

MongoDB Compass (建議安裝)

本文章是使用本地端進行測試,先打開 MongoDB Compass 在一開始的 New Connection 中輸入 mongodb://localhost:27017/ 然後按下 Connect。

Image

成功利用 Compass 連線至本地端的 MongoDB 後,可以在左邊的 Databases 看到預設有三個資料庫,但目前還沒有對資料庫進行任何的操作,所以不會看到我們建立的資料庫(testdb)。

Image

建立 Collections 定義 Schema 並新增資料到資料庫

我們現在可以透過 Mongoose 來建立資料庫的 Collection,如果你有使用過其他資料庫例如 Mysql,Collection 就像是 Table,而 Table 在建立時需要定義裡面的資料欄位名稱以及資料型態(Schema Type),Collection 也是一樣。

要知道 Mongoose 支援哪些 Schema Type 的話可以看官方的文檔,這裡就不多介紹了。

現在就來建立我們的 Collection 並定義 Schema 吧

我們再建立一支檔案名為 User.js,在該檔案裡面引入 mongoose 套件,並定義 Collection 名稱與欄位名稱。

User.js
const mongoose = require("mongoose");//定義欄位名稱與欄位型態const userSchema = new mongoose.Schema({  name: String,  email: String,  age: Number,});//定義Collection的名稱module.exports = mongoose.model("User", userSchema);

定義好 Collection 名稱和 欄位名稱後,我們直接在 server.js 檔案中引入做使用,要注意的是 mongoose 提供的新增修改刪除都必須使用 async / await 去做處理,在建立新資料的時候填入剛剛定義的欄位名稱(key)還有欄位的值(value)。

server.js
const mongoose = require("mongoose");const User = require("./User");//如果是使用cloud的話 第一個參數就要放cloud給予的uri位置,在<password>的部分要改成自己的MongoDB密碼,才能成功連線。//本地端預設: mongodb://127.0.0.1:27017/你自己的資料庫名稱//cloud:mongodb+srv://Wei:<password>@cluster0.adryn.mongodb.net/?retryWrites=true&w=majoritymongoose.connect("mongodb://127.0.0.1:27017/testdb", () => {  console.log("connected");});const createNewData = async () => {  try {    // 第一種建立資料的方法    // const user = new User({ name: "Wei", age: 24 });    // await user.save();    //----------------------------------------    //第二種建立資料的方法    const user = await User.create({      name: "Wei",      age: 24,      email: "test@gmail.com",    });    console.log(user);  } catch (error) {    console.log(error.message);  }};createNewData();

將上面的程式碼貼到 server.js 後儲存,因為我們是使用 nodemon 的關係,在按下儲存的當下 nodemon 就會幫我們重啟 server,如果沒有報出任何錯誤並且有在 Terminal 看到我們新增的資料,就代表資料建立成功了。

在 MongoDB Compass 中按下左邊的重新整理按鈕,就會看到我們的資料庫(testdb)和 collection 了(users),而在 collection 裡面可以看到剛剛新增的資料。

Image

而如果要一次新增多筆資料的話就得使用 insertMany,差別在於傳入的參數必需用陣列包起來。

server.js
const mongoose = require("mongoose");const User = require("./User");//如果是使用cloud的話 第一個參數就要放cloud給予的uri位置,在<password>的部分要改成自己的MongoDB密碼,才能成功連線。//本地端預設: mongodb://127.0.0.1:27017/你自己的資料庫名稱//cloud:mongodb+srv://Wei:<password>@cluster0.adryn.mongodb.net/?retryWrites=true&w=majoritymongoose.connect("mongodb://127.0.0.1:27017/testdb", () => {  console.log("connected");});const createNewData = async () => {  try {    // 第一種建立資料的方法    // const user = new User({ name: "Wei", age: 24 });    // await user.save();    //----------------------------------------    //第二種建立資料的方法    // const user = await User.create({    //   name: "Wei",    //   age: 24,    //   email: "test@gmail.com",    // });    //一次新增多筆資料    const user = await User.insertMany([      {        name: "Alex",        age: 18,        email: "test1122123@gmail.com",      },      {        name: "Bob",        age: 16,        email: "test5577@gmail.com",      },    ]);    console.log(user);  } catch (error) {    console.log(error.message);  }};createNewData();

如新增多筆資料成功的話,可以在 Terminal 看到剛剛新增的資料。

Image

在 Schema 中進行資料驗證

在定義 Schema 的時候,通常會針對某些欄位進行驗證(validate),例如:該欄位在新增時為必需的(required)、欄位最小值應為 1(min),最大值為 100(max)等…。

而如果需針對欄位進行驗證,必需使用物件的方式來定義欄位屬性。

User.js
const mongoose = require("mongoose");//定義欄位名稱與欄位型態const userSchema = new mongoose.Schema({  name: {    type: String,    required: true,  },  email: {    type: String,    required: true,    //email字串欄位最小長度應為10    minLength: 10,  },  age: {    type: Number,    required: true,    //age數字欄位最小值應為1    min: 1,  },});//定義Collection的名稱module.exports = mongoose.model("User", userSchema);

接著到 server.js 修改一下資料的值

server.js
const mongoose = require("mongoose");const User = require("./User");//如果是使用cloud的話 第一個參數就要放cloud給予的uri位置,在<password>的部分要改成自己的MongoDB密碼,才能成功連線。//本地端預設: mongodb://127.0.0.1:27017/你自己的資料庫名稱//cloud:mongodb+srv://Wei:<password>@cluster0.adryn.mongodb.net/?retryWrites=true&w=majoritymongoose.connect("mongodb://127.0.0.1:27017/testdb", () => {  console.log("connected");});const createNewData = async () => {  try {    const user = await User.create({      name: "Wei",      age: -1,      email: "test@gmail.com",    });    console.log(user);  } catch (error) {    console.log(error.message);  }};createNewData();

按下儲存後,會發現 Terminal 報出錯誤訊息,原因是因為在 age 的欄位定義了規則,規定 age 欄位最小的值只能為 1,而建立的資料為-1。

Image

Schema 自訂義規則

我們也可以在 Schema 中撰寫自己的欄位規則。

在 age 欄位中,我們建立了一個新屬性叫做 validate,在 validate 裡面需傳入 validator 以及 message,validtor 為你自己定義的欄位規則,在該欄位去判斷 age 傳進來的值是否為偶數,而當 validator 為 true 的時候才能通過驗證,如果驗證失敗,則會回傳 message。

User.js
const mongoose = require("mongoose");//定義欄位名稱與欄位型態const userSchema = new mongoose.Schema({  name: {    type: String,    required: true,  },  email: {    type: String,    required: true,    minLength: 10,  },  age: {    type: Number,    required: true,    min: 1,    validate: {      // validator為true時,才能通過驗證。      validator: (v) => v % 2 === 0,      message: (props) => `${props.value} 並不是偶數`,    },  },});//定義Collection的名稱module.exports = mongoose.model("User", userSchema);

這邊將 age 的值改為奇數並儲存。

server.js
const mongoose = require("mongoose");const User = require("./User");//如果是使用cloud的話 第一個參數就要放cloud給予的uri位置,在<password>的部分要改成自己的MongoDB密碼,才能成功連線。//本地端預設: mongodb://127.0.0.1:27017/你自己的資料庫名稱//cloud:mongodb+srv://Wei:<password>@cluster0.adryn.mongodb.net/?retryWrites=true&w=majoritymongoose.connect("mongodb://127.0.0.1:27017/testdb", () => {  console.log("connected");});const createNewData = async () => {  try {    const user = await User.create({      name: "Wei",      age: 23, // 23 為奇數      email: "test@gmail.com",    });    console.log(user);  } catch (error) {    console.log(error.message);  }};createNewData();

儲存後會發現驗證失敗,因為 23 並不是偶數。

Image