- 1. MongoDB คืออะไร
- 2. โครงสร้างข้อมูลของ MongoDB
- 3. จุดเด่นและข้อควรระวัง
- 4. การติดตั้ง MongoDB ด้วย Docker Compose
- 5. การใช้งาน MongoDB Shell
- 6. CRUD Operations
- 7. การออกแบบข้อมูล: Embed หรือ Reference
- 8. Index และประสิทธิภาพ
- 9. Aggregation Pipeline
- 10. ตัวอย่างเชื่อมต่อด้วย Node.js
- 11. ความปลอดภัยและการดูแลระบบ
- 12. MongoDB เหมาะกับงานแบบใด
- 13. สรุปแนวคิดสำคัญ
- แหล่งอ้างอิง
MongoDB เป็นฐานข้อมูลแบบ NoSQL ที่จัดเก็บข้อมูลในรูปแบบ Document โดยใช้โครงสร้างคล้าย JSON และจัดเก็บจริงในรูปแบบ BSON จุดเด่นคือความยืดหยุ่นของโครงสร้างข้อมูล การรองรับข้อมูลที่เปลี่ยนแปลงได้ และการเขียน Query ที่เหมาะกับรูปแบบข้อมูลของแอปพลิเคชัน
บทความนี้อธิบายแนวคิดสำคัญของ MongoDB ตั้งแต่โครงสร้างพื้นฐาน การทำ CRUD การออกแบบข้อมูล การสร้าง Index การใช้ Aggregation ไปจนถึงตัวอย่างการเชื่อมต่อกับ Backend
#1. MongoDB คืออะไร
MongoDB เป็นฐานข้อมูลแบบ Document-Oriented Database ซึ่งข้อมูลถูกจัดเก็บเป็นเอกสารใน Collection แทนการจัดเก็บเป็นแถวและคอลัมน์แบบฐานข้อมูลเชิงสัมพันธ์
ตัวอย่างเอกสารผู้ใช้งาน:
{
"_id": "u1001",
"name": "Naruapon",
"email": "naruapon@example.com",
"roles": ["instructor", "researcher"],
"profile": {
"department": "Software Engineering",
"organization": "NPRU"
},
"createdAt": "2026-10-18T00:00:00Z"
}
เอกสารหนึ่งรายการสามารถมี Object ซ้อนกันและ Array ได้ จึงเหมาะกับข้อมูลที่มีโครงสร้างใกล้เคียงกับ Object ในโปรแกรม
#2. โครงสร้างข้อมูลของ MongoDB
| MongoDB | แนวคิดที่ใกล้เคียงใน SQL |
|---|---|
| Database | Database |
| Collection | Table |
| Document | Row |
| Field | Column |
| Embedded Document | ข้อมูลที่ฝังอยู่ภายใน Row |
| Array | กลุ่มค่าหรือรายการย่อย |
ตัวอย่างลำดับโครงสร้าง:
MongoDB Server
└── Database: university
└── Collection: lecturers
└── Document
├── name
├── email
└── researchAreas[]
MongoDB ไม่ได้บังคับให้ทุก Document ใน Collection ต้องมี Field เหมือนกันทั้งหมด แต่ในระบบจริงควรออกแบบ Schema ให้มีมาตรฐาน เพื่อให้ Query การตรวจสอบข้อมูล และการดูแลระบบทำได้ง่าย
#3. จุดเด่นและข้อควรระวัง
#จุดเด่น
- เก็บข้อมูลแบบ Nested Object และ Array ได้โดยตรง
- เหมาะกับข้อมูลที่มีโครงสร้างเปลี่ยนแปลงบ่อย
- Query และ Aggregation มีความยืดหยุ่น
- ขยายระบบด้วย Replication และ Sharding ได้
- มี Driver สำหรับหลายภาษา เช่น JavaScript, Java, Python, Go, C# และ PHP
- เหมาะกับระบบ Web API, Event Data, Catalog, Content และระบบที่ต้องพัฒนาเร็ว
#ข้อควรระวัง
- Flexible Schema ไม่ได้หมายความว่าไม่ต้องออกแบบข้อมูล
- การฝังข้อมูลมากเกินไปอาจทำให้ Document ใหญ่และแก้ไขยาก
- Index ช่วยให้การอ่านเร็วขึ้น แต่เพิ่มต้นทุนในการเขียนและใช้พื้นที่
- ความสัมพันธ์ที่ซับซ้อนมากอาจเหมาะกับการอ้างอิงหรือฐานข้อมูลเชิงสัมพันธ์มากกว่า
- ควรวางแผนเรื่องสิทธิ์ การสำรองข้อมูล และการตรวจสอบ Schema ตั้งแต่เริ่มต้น
#4. การติดตั้ง MongoDB ด้วย Docker Compose
ตัวอย่างไฟล์ compose.yaml สำหรับการทดลองในเครื่อง:
services:
mongodb:
image: mongo:8
container_name: mongodb-dev
restart: unless-stopped
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: change-me
volumes:
- mongodb_data:/data/db
volumes:
mongodb_data:
คำสั่งเริ่มต้นระบบ:
docker compose up -d
docker compose ps
คำสั่งเชื่อมต่อด้วย mongosh:
mongosh "mongodb://admin:change-me@localhost:27017/?authSource=admin"
สำหรับ Production ควรใช้ Secret หรือระบบจัดการความลับแทนการเขียนรหัสผ่านไว้ในไฟล์โดยตรง
#5. การใช้งาน MongoDB Shell
เลือก Database ที่ต้องการใช้งาน:
use university
สร้างข้อมูลหนึ่งรายการ:
db.lecturers.insertOne({
name: "Naruapon Suwanwijit",
email: "naruapon@example.com",
department: "Software Engineering",
researchAreas: ["Software Testing", "AI Agents", "RAG"],
active: true
})
สร้างหลายรายการ:
db.lecturers.insertMany([
{
name: "Kanchana Viriyapant",
department: "Computer Science",
active: true
},
{
name: "Nalinpat Bhumpenpien",
department: "Information Technology",
active: true
}
])
#6. CRUD Operations
CRUD ประกอบด้วย Create, Read, Update และ Delete
#Create
db.students.insertOne({
studentId: "S001",
name: "Somchai",
program: "Software Engineering",
gpa: 3.45
})
#Read
อ่านข้อมูลทั้งหมด:
db.students.find()
ค้นหาด้วยเงื่อนไข:
db.students.find({
program: "Software Engineering",
gpa: { $gte: 3.00 }
})
เลือกเฉพาะ Field ที่ต้องการ:
db.students.find(
{ gpa: { $gte: 3.00 } },
{ _id: 0, studentId: 1, name: 1, gpa: 1 }
)
#Update
db.students.updateOne(
{ studentId: "S001" },
{
$set: { gpa: 3.60 },
$currentDate: { updatedAt: true }
}
)
เพิ่มสมาชิกใน Array โดยไม่เพิ่มค่าซ้ำ:
db.students.updateOne(
{ studentId: "S001" },
{ $addToSet: { skills: "MongoDB" } }
)
#Delete
db.students.deleteOne({ studentId: "S001" })
ควรใช้ Filter ที่ชัดเจนเสมอ และตรวจสอบผลลัพธ์ก่อนใช้ deleteMany() ในระบบจริง
#7. การออกแบบข้อมูล: Embed หรือ Reference
#Embed: ฝังข้อมูลไว้ใน Document เดียวกัน
เหมาะเมื่อข้อมูลถูกใช้งานร่วมกันบ่อย มีขนาดไม่ใหญ่ และต้องการอ่านด้วย Query เดียว
{
"orderNo": "ORD-1001",
"customer": {
"name": "Somchai",
"email": "somchai@example.com"
},
"items": [
{ "productId": "P01", "name": "Keyboard", "quantity": 1 },
{ "productId": "P02", "name": "Mouse", "quantity": 2 }
]
}
#Reference: เก็บรหัสอ้างอิงไปยัง Document อื่น
เหมาะเมื่อข้อมูลมีขนาดใหญ่ ถูกใช้งานร่วมกันหลายส่วน หรือมีการเปลี่ยนแปลงแยกจากกันบ่อย
{
"orderNo": "ORD-1001",
"customerId": "C001",
"items": [
{ "productId": "P01", "quantity": 1 }
]
}
หลักสำคัญคือออกแบบตาม Query ที่ระบบต้องใช้จริง ไม่ควรแปลงตารางจาก SQL เป็น Collection แบบหนึ่งต่อหนึ่งโดยไม่พิจารณารูปแบบการอ่านข้อมูล
#8. Index และประสิทธิภาพ
สร้าง Index สำหรับ Field ที่ใช้ค้นหา เรียงลำดับ หรือกรองข้อมูลบ่อย:
db.students.createIndex({ studentId: 1 }, { unique: true })
db.students.createIndex({ program: 1, gpa: -1 })
ตรวจสอบแผนการทำงานของ Query:
db.students
.find({ program: "Software Engineering" })
.explain("executionStats")
แนวทางที่ควรทำ:
- เริ่มจาก Query ที่ระบบใช้งานจริง
- สร้าง Index ให้ตรงกับ Filter และ Sort
- ตรวจสอบด้วย
explain() - ติดตาม Index ที่ไม่ได้ใช้งาน
- หลีกเลี่ยงการสร้าง Index จำนวนมากโดยไม่มีเหตุผล
#9. Aggregation Pipeline
Aggregation Pipeline คือกระบวนการนำ Document ผ่านหลาย Stage เพื่อกรอง จัดกลุ่ม เรียงลำดับ และคำนวณผลลัพธ์
ตัวอย่างหาค่าเฉลี่ย GPA แยกตามหลักสูตร:
db.students.aggregate([
{
$match: { active: true }
},
{
$group: {
_id: "$program",
averageGpa: { $avg: "$gpa" },
totalStudents: { $sum: 1 }
}
},
{
$sort: { averageGpa: -1 }
}
])
Stage ที่พบได้บ่อย:
| Stage | หน้าที่ |
|---|---|
$match |
กรอง Document |
$project |
เลือกหรือคำนวณ Field |
$group |
จัดกลุ่มและสรุปผล |
$sort |
เรียงลำดับ |
$limit |
จำกัดจำนวนผลลัพธ์ |
$lookup |
เชื่อมข้อมูลจาก Collection อื่น |
$unwind |
แยกสมาชิกใน Array ออกเป็นหลาย Document |
ควรใช้ $match ในช่วงต้นของ Pipeline เมื่อทำได้ เพื่อให้ข้อมูลที่ต้องประมวลผลลดลง
#10. ตัวอย่างเชื่อมต่อด้วย Node.js
ติดตั้ง MongoDB Driver:
npm install mongodb
ตัวอย่างการเชื่อมต่อ:
import { MongoClient } from "mongodb";
const uri = process.env.MONGODB_URI;
const client = new MongoClient(uri);
async function main() {
await client.connect();
const db = client.db("university");
const lecturers = db.collection("lecturers");
await lecturers.insertOne({
name: "Naruapon",
department: "Software Engineering",
active: true
});
const result = await lecturers
.find({ active: true })
.sort({ name: 1 })
.toArray();
console.log(result);
await client.close();
}
main().catch(console.error);
ใน Production ควรจัดการ Connection Pool ให้เหมาะสม ไม่เปิด Connection ใหม่ทุก Request และควรเก็บ Connection String ไว้ใน Environment Variable
#11. ความปลอดภัยและการดูแลระบบ
- เปิด Authentication และกำหนด Role ตามหลัก Least Privilege
- ไม่เปิด Port ของฐานข้อมูลสู่สาธารณะโดยไม่จำเป็น
- ใช้ TLS สำหรับการเชื่อมต่อที่ผ่านเครือข่ายที่ไม่ปลอดภัย
- แยกฐานข้อมูล Development, Staging และ Production
- กำหนด Backup และทดสอบการ Restore เป็นระยะ
- ตรวจสอบ Slow Query, Error Log และการใช้ทรัพยากร
- ใช้ Schema Validation เมื่อข้อมูลมีรูปแบบที่ต้องควบคุม
- หลีกเลี่ยงการเก็บรหัสผ่านแบบ Plain Text
ตัวอย่าง Schema Validation แบบง่าย:
db.createCollection("students", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["studentId", "name", "gpa"],
properties: {
studentId: { bsonType: "string" },
name: { bsonType: "string" },
gpa: { bsonType: "double", minimum: 0, maximum: 4 }
}
}
}
})
#12. MongoDB เหมาะกับงานแบบใด
MongoDB เหมาะกับระบบที่มีข้อมูลเป็นเอกสารหรือข้อมูลกึ่งโครงสร้าง เช่น
- REST API และ Backend ของ Web Application
- Product Catalog ที่แต่ละสินค้าอาจมี Attribute ไม่เหมือนกัน
- ระบบ Content และบทความ
- Event และ Log Data
- ระบบที่ต้องพัฒนา Schema อย่างต่อเนื่อง
- ระบบ Real-time ที่ใช้ Change Streams
- ระบบค้นหาและวิเคราะห์ข้อมูลเอกสาร
MongoDB อาจไม่ใช่ตัวเลือกแรกเมื่อระบบมี Transaction ซับซ้อนมาก ความสัมพันธ์ระหว่างข้อมูลมีจำนวนมาก หรือรายงานต้องใช้ Join เชิงตารางเป็นหลัก แม้ MongoDB จะมี Transaction และ $lookup รองรับก็ตาม
#13. สรุปแนวคิดสำคัญ
- MongoDB จัดเก็บข้อมูลเป็น Document ใน Collection
- Document รองรับ Object ซ้อนและ Array ทำให้ใกล้เคียงกับโครงสร้างข้อมูลในโปรแกรม
- Flexible Schema ต้องใช้ร่วมกับมาตรฐานข้อมูลและ Validation ที่เหมาะสม
- ออกแบบข้อมูลตาม Query และรูปแบบการใช้งานจริง
- ใช้ Index กับ Query ที่สำคัญ และตรวจสอบด้วย
explain() - ใช้ Aggregation Pipeline สำหรับการกรอง จัดกลุ่ม และคำนวณข้อมูล
- Production ต้องให้ความสำคัญกับ Authentication, Backup, Monitoring และการจำกัดสิทธิ์