Mongoose Schema:資料建模與 CRUD 完整操作指南
在 Mongoose 的世界中,所有操作都圍繞著兩個核心:Schema (定義資料結構的藍圖) 與 Model (根據藍圖產出的操作工具)。掌握它們,你就能在 Node.js 中優雅地操縱 MongoDB。
定義 Schema 與資料校驗
Schema 不僅定義欄位,還負責資料的完整性。
const mongoose = require('mongoose');
const postSchema = new mongoose.Schema(
{
title: {
type: String,
required: [true, '標題為必填'],
trim: true, // 自動修剪空格
maxLength: [100, '標題太長了'],
},
content: {
type: String,
required: [true, '內容不可為空'],
},
status: {
type: String,
enum: ['draft', 'published'], // 限定值範圍
default: 'draft',
},
author: {
type: mongoose.Schema.ObjectId, // 建立與 User 集合的關聯
ref: 'User',
},
},
{ timestamps: true }
); // 自動生成 createdAt 與 updatedAt
const Post = mongoose.model('Post', postSchema);
module.exports = Post;
實戰 CRUD:基礎與進階操作
1. Create (建立)
const post = await Post.create({
title: 'Node.js 與 Mongoose 實戰',
content: '這是一篇深度解析的文章...',
});
2. Read (讀取與關聯)
當你有關聯資料時,使用 populate 可以像 SQL 的 JOIN 一樣拉出詳細資訊。
// 尋找文章並同時抓取作者的 name 資訊
const posts = await Post.find().populate('author', 'name');
// 效能優化:如果是唯讀操作,使用 lean() 能轉為原生物件,大幅提升速度
const fastResult = await Post.find().lean();
3. Update (更新)
// 注意:findByIdAndUpdate 預設不會觸發 Schema 的驗證,需加上 runValidators
const updated = await Post.findByIdAndUpdate(
id,
{ status: 'published' },
{ new: true, runValidators: true }
);
4. Delete (刪除)
await Post.findByIdAndDelete(id);
進階:Middleware (Hooks) 的應用
最常見的用法是在存檔前對密碼進行處理,或是在內容變動時記錄日誌。
// 在存檔 (save) 之前自動執行的邏輯
postSchema.pre('save', function (next) {
this.title = this.title.toUpperCase(); // 強制轉換為大寫
next();
});
實務建議:Instance vs Static Methods
- Instance Method:針對「特定一筆資料」的方法(如
user.checkPassword())。 - Static Method:針對「整張表」的查詢邏輯(如
Post.findByCategory())。
總結
- Schema 是資料的防線,善用內建的校驗器(required, enum, match)。
- 在大量讀取且不需要修改資料時,務必開啟
.lean()模式優化效能。 - 建立 Model 關聯 並使用
populate()能讓你輕鬆處理複雜的資料鏈結。