บทความนี้คือจุดเริ่มต้นสำหรับผู้ที่อยากเข้าใจ NoSQL Database ตั้งแต่แนวคิด รูปแบบข้อมูล JSON ประเภทของ NoSQL ไปจนถึงการใช้งาน MongoDB ซึ่งเป็น NoSQL ยอดนิยมที่เก็บข้อมูลเป็นเอกสาร (Document) พร้อมตัวอย่างคำสั่งตั้งแต่สร้าง เพิ่ม ค้น แก้ไข ลบ ไปจนถึง Aggregation และมี แบบฝึกหัด ท้ายแต่ละหัวข้อ
1. NoSQL คืออะไร#
NoSQL (ย่อมาจาก “Not Only SQL”) คือกลุ่มของระบบจัดการฐานข้อมูลที่ออกแบบมาเพื่อรองรับการทำงานที่ Relational Database (RDBMS) แบบดั้งเดิมตอบโต้ได้ยาก เช่น ข้อมูลปริมาณมหาศาล โครงสร้างข้อมูลที่เปลี่ยนแปลงบ่อย และการขยายตัวแบบกระจาย (horizontal scaling)
จุดเด่นของ NoSQL คือ Schema ยืดหยุ่น — ไม่ต้องกำหนดโครงสร้างตารางที่ตายตัวล่วงหน้า แต่ละระเบียน (record) สามารถมีฟิลด์ที่ต่างกันได้ ทำให้เพิ่มฟิลด์ใหม่ได้โดยไม่ต้อง ALTER TABLE และเก็บข้อมูลที่ซ้อนกัน (nested) หรือเป็นกลุ่มไม่จำกัดได้ตามธรรมชาติ

NoSQL เกิดขึ้นเพื่อตอบโจทย์ 4 ด้านหลัก ได้แก่
ปริมาณข้อมูลมหาศาล (Big Data)#
NoSQL ออกแบบมาให้กระจายข้อมูลข้ามเซิร์ฟเวอร์หลายเครื่องได้ (sharding) ยิ่งข้อมูลเพิ่มขึ้น ก็เพิ่มเซิร์ฟเวอร์เข้าไปได้เรื่อย ๆ แทนที่จะต้องซื้อเครื่องเดียวที่แพงและทรงพลังมากขึ้นเรื่อย ๆ แบบ RDBMS แบบเดิม
โครงสร้างข้อมูลเปลี่ยนแปลงบ่อย (Flexible Schema)#
ในแอปพลิเคชันสมัยใหม่ โครงสร้างข้อมูลมักเปลี่ยนไปตามการพัฒนา NoSQL ให้เพิ่มหรือเปลี่ยนฟิลด์ได้โดยไม่ต้อง migrate ตารางทั้งตาราง เหมาะกับ rapid prototyping และข้อมูลที่หลากหลาย
ความเร็วสูง (Performance)#
NoSQL หลายประเภทเสียสละความสามารถบางอย่างของ RDBMS (เช่น JOIN ที่ซับซ้อน, transaction แบบเข้มข้น) เพื่อแลกกับความเร็วในการอ่าน/เขียนที่สูงมาก เช่น Redis ที่เก็บข้อมูลใน memory
รูปแบบข้อมูลหลากหลาย (Variety)#
NoSQL รองรับข้อมูลหลายรูปแบบ โดยแบ่งเป็น 4 ประเภทหลัก แต่ละประเภทเก็บข้อมูลคนละแบบ เหมาะกับงานคนละแบบ:
- Document — เก็บข้อมูลเป็นเอกสารคล้าย JSON ที่ซ้อนกันได้ และแต่ละเอกสารมีฟิลด์ต่างกันได้ เหมาะกับข้อมูลเอกสาร/catalog (เช่น MongoDB)
- Key-Value — เก็บเป็นคู่คีย์-ค่าเรียบง่าย อ่าน/เขียนเร็วมาก เหมาะกับ cache, session (เช่น Redis)
- Wide Column — เก็บเป็นตารางที่แต่ละแถวมีคอลัมน์ต่างกันได้ รองรับข้อมูลปริมาณมหาศาล เหมาะกับ time-series, log (เช่น Cassandra)
- Graph — เก็บเป็นโหนด (node) และความสัมพันธ์ (edge) เน้นความสัมพันธ์ระหว่างข้อมูล เหมาะกับ social network, ระบบแนะนำ (เช่น Neo4j)
การเลือกประเภทให้ตรงกับลักษณะของข้อมูลเป็นหัวใจสำคัญ — รายละเอียดเปรียบเทียบแบบเต็มจะอธิบายในหัวข้อประเภทของ NoSQL
สรุป: NoSQL ไม่ได้มาแทน RDBMS แต่มาเสริม — เลือกใช้ตามลักษณะงาน เช่น ข้อมูลเอกสาร/hierarchical เลือก Document DB, ข้อมูลแคชเร็วเลือก Key-Value
📝 แบบฝึกหัด
- จงอธิบายด้วยคำพูดของคุณเองว่า ทำไม RDBMS อาจไม่เหมาะกับข้อมูลที่โครงสร้างเปลี่ยนแปลงบ่อย
- ยกตัวอย่าง แอปพลิเคชัน 1 อย่างที่คิดว่า NoSQL เหมาะกว่า RDBMS พร้อมเหตุผล
2. JSON คืออะไร#
ก่อนเข้าใจ Document Database อย่าง MongoDB ต้องเข้าใจ JSON เสียก่อน เพราะ MongoDB เก็บข้อมูลในรูปแบบที่คล้าย JSON มาก
JSON (JavaScript Object Notation) คือรูปแบบข้อความ (text) สำหรับจัดเก็บและแลกเปลี่ยนข้อมูล ที่ทั้งมนุษย์อ่านง่ายและเครื่องจัดประมวลผลได้สะดวก แม้ชื่อจะมีคำว่า JavaScript แต่ JSON เป็นรูปแบบอิสระ — ภาษาเกือบทุกภาษา (Python, Java, PHP, Go, ฯลฯ) อ่าน/เขียน JSON ได้

โครงสร้างพื้นฐานของ JSON#
JSON ประกอบด้วย คู่คีย์-ค่า (key-value) เขียนอยู่ในเครื่องหมายปีกกา { } คีย์ต้องเป็นข้อความที่อยู่ในเครื่องหมายคำพูดคู่ " " ส่วนค่าสามารถเป็นได้หลายชนิด
{
"name": "Wireless Mouse",
"price": 590,
"inStock": true,
"rating": 4.5,
"tags": ["wireless", "ergonomic"],
"specs": {
"color": "black",
"battery": "AAA"
},
"discount": null
}json💡 ทริค: แนะนำให้เขียน JSON ใน VS Code เพราะโปรแกรมจะช่วยเช็ค syntax ให้ทันที เช่น ลืมใส่จุลภาค
,ใช้เครื่องหมายคำพูดผิดแบบ (เช่น single quote แทน double quote) หรือลืมปิดปีกกา — VS Code จะขีดเส้นแดงแจ้งเตือน ทำให้เขียน JSON ให้ถูกต้องได้ง่ายและเร็วขึ้นมาก (หากยังไม่มี ดาวน์โหลดได้ฟรีที่ code.visualstudio.com ↗)
ชนิดข้อมูลใน JSON#
| ชนิด | ตัวอย่าง | คำอธิบาย |
|---|---|---|
| String | "Wireless Mouse" | ข้อความ ใส่ในเครื่องหมายคำพูดคู่เสมอ |
| Number | 590, 4.5 | ตัวเลข (ทั้งจำนวนเต็มและทศนิยม) |
| Boolean | true, false | ค่าจริง/เท็จ (ไม่ใส่เครื่องหมายคำพูด) |
| Null | null | ค่าว่าง (ไม่ใส่เครื่องหมายคำพูด) |
| Array | ["wireless", "ergonomic"] | ลำดับของค่า อยู่ใน [ ] |
| Object | { "color": "black" } | คู่คีย์-ค่า อยู่ใน { } (ซ้อนกันได้) |
จุดที่ทำให้ JSON ทรงพลังคือ Object และ Array สามารถซ้อนกันได้ลึกไม่จำกัด เช่น specs เป็น object ที่ซ้อนใน object ใหญ่ หรือ tags เป็น array ของข้อความ คุณสมบัตินี้ทำให้ JSON เก็บข้อมูลที่มีโครงสร้างซับซ้อน (hierarchical) ได้อย่างเป็นธรรมชาติ
ทำไม JSON จึงสำคัญ#
- แลกเปลี่ยนข้อมูลระหว่างระบบ — REST API ส่ง/รับข้อมูลเป็น JSON เกือบทั้งหมด
- ไฟล์ตั้งค่า (config) — เช่น
package.json,tsconfig.json - เป็นรากฐานของ Document Database — MongoDB เก็บแต่ละ record เป็นเอกสารรูปแบบ JSON (จริง ๆ คือ BSON ซึ่งเป็น JSON แบบ binary จะอธิบายในหัวข้อถัดไป)
เคล็ดลับ — ความผิดพลาดที่พบบ่อย: คีย์ของ JSON ต้องใส่เครื่องหมางคำพูดคู่เสมอ (
"name"ไม่ใช่name) และห้ามมี comma ต่อท้ายคู่สุดท้าย (trailing comma) มิฉะนั้นจะ parse ไม่ผ่าน
สรุป: JSON เป็นรูปแบบข้อความ key-value ที่มนุษย์และเครื่องอ่านได้ รองรับชนิดข้อมูล 6 แบบ และ object/array ซ้อนกันได้ จึงเป็นรากฐานของ document database และการแลกเปลี่ยนข้อมูลทุกวันนี้
📝 แบบฝึกหัด
- จงเขียน JSON ของสินค้า “Notebook” ราคา 35 หมวด Stationery มีแท็ก
["school", "office"]และมีinStockเป็นจริง - JSON ต่อไปนี้มี 2 จุดที่ผิด จงแก้ให้ถูกต้อง:
{ name: 'Pen', price: 20, } - ค่า
20และtrueใน JSON เป็นชนิดข้อมูลใด? (จงตอบโดยไม่ใส่เครื่องหมายคำพูด)
3. SQL vs NoSQL — เลือกแบบไหน#
ทั้งสองแบบไม่ได้ดีกว่ากันอย่างเด็ดขาด แต่เหมาะกับงานต่างกัน
| ด้าน | Relational (SQL) | NoSQL |
|---|---|---|
| โครงสร้าง | ตาราง (table) แถว/คอลัมน์ มี schema ตายตัว | เอกสาร/คีย์-ค่า/คอลัมน์/กราฟ schema ยืดหยุ่น |
| ภาษา | SQL | ขึ้นกับระบบ (MongoDB ใช้คำสั่งแบบ JavaScript) |
| ความสัมพันธ์ | JOIN ระหว่างตาราง, foreign key | มักฝังข้อมูลที่เกี่ยวข้องไว้ด้วยกัน (embed) |
| การขยาย | มักขยายเครื่องเดียวให้แรงขึ้น (vertical) | กระจายข้ามหลายเครื่องได้ดี (horizontal) |
| Transaction | แข็งแกร่ง (ACID) | มีบ้างแต่มักเน้นความเร็ว/ปริมาณ |
| ตัวอย่าง | MySQL, PostgreSQL, Oracle | MongoDB, Redis, Cassandra |
| เหมาะกับ | ข้อมูลมีโครงสร้างชัดเจน ความสัมพันธ์ซับซ้อน (banking, ERP) | ข้อมูลหลากหลาย/ซ้อนกัน ปริมาณมาก เปลี่ยนบ่อย (content, IoT, real-time) |
สรุป: เลือก SQL เมื่อข้อมูลมีโครงสร้างตายตัวและต้องการความสัมพันธ์/transaction ที่เข้มข้น เลือก NoSQL เมื่อต้องการความยืดหยุ่น ความเร็ว และรองรับข้อมูลปริมาณมหาศาล
📝 แบบฝึกหัด
- ระบบ ธนาคาร/บัญชีเงินฝาก ควรใช้ SQL หรือ NoSQL? เพราะอะไร?
- แอปเก็บ log การคลิกของผู้ใช้นับล้าน record ต่อวัน ควรใช้แบบไหน? เพราะอะไร?
4. ประเภทของ NoSQL Database#
NoSQL แบ่งเป็น 4 ประเภทหลัก ตามรูปแบบการจัดเก็บข้อมูล

| ประเภท | รูปแบบข้อมูล | ตัวอย่าง | เหมาะกับ |
|---|---|---|---|
| Document | เอกสารคล้าย JSON | MongoDB, CouchDB | ข้อมูลเอกสาร/hierarchical, content, catalog |
| Key-Value | คู่คีย์-ค่าเรียบง่าย | Redis, DynamoDB | cache, session, counter ความเร็วสูง |
| Wide Column | ตารางที่แต่ละแถวมีคอลัมน์ต่างกันได้ | Cassandra, HBase | ข้อมูล time-series, log, ปริมาณมาก |
| Graph | โหนตและความสัมพันธ์ (node & edge) | Neo4j, ArangoDB | social network, recommendation, fraud detection |
ในบทความนี้เราจะเน้นที่ Document Database โดยใช้ MongoDB เพราะเป็น NoSQL ที่นิยมและเข้าใจง่ายที่สุด และเก็บข้อมูลในรูปแบบ JSON ซึ่งนักพัฒนาคุ้นเคย
สรุป: เลือกประเภทตามลักษณะข้อมูล — เอกสาร→Document, แคชเร็ว→Key-Value, ปริมาณมากตามเวลา→Wide Column, ความสัมพันธ์ซับซ้อน→Graph
📝 แบบฝึกหัด
จงจับคู่ งาน กับ ประเภท NoSQL ที่เหมาะสมที่สุด (Document / Key-Value / Wide Column / Graph)
- ระบบแนะนำเพื่อนบนโซเชียลเน็ตเวิร์ก
- เก็บ session ผู้ใช้ชั่วคราวที่ต้องอ่านเร็วมาก
- เก็บบทความบล็อกที่มีคอมเมนต์ซ้อนอยู่ข้างใน
- เก็บข้อมูลเซนเซอร์อุณหภูมิทุกนาทีนับล้านจุดต่อวัน
5. MongoDB คืออะไร#
MongoDB คือ Document Database ยอดนิยมที่เก็บข้อมูลเป็น เอกสาร (Document) ในรูปแบบคล้าย JSON จริง ๆ แล้ว MongoDB เก็บเป็น BSON (Binary JSON) ซึ่งเป็น JSON ในรูปแบบ binary ที่ทำให้ค้นหาและประมวลผลได้เร็วขึ้น และรองรับชนิดข้อมูลเพิ่มเติม เช่น Date, ObjectId
Vocabulary — เปรียบเทียบกับ RDBMS#
| RDBMS | MongoDB | คำอธิบาย |
|---|---|---|
| Database | Database | คอนเทนเนอร์รวม (เหมือนกัน) |
| Table | Collection | ที่เก็บกลุ่มของเอกสาร |
| Row | Document | หนึ่งระเบียนข้อมูล (JSON-like) |
| Column | Field | คู่คีย์-ค่าหนึ่งคู่ในเอกสาร |
| Primary Key | _id | ระบุเอกสารให้ไม่ซ้ำ (สร้างอัตโนมัติ) |
SELECT * FROM table | db.collection.find() | ดึงข้อมูล |

ข้อแตกต่างสำคัญ: ใน RDBMS ทุกแถวในตารางต้องมีคอลัมน์เหมือนกัน แต่ใน MongoDB แต่ละเอกสารใน collection เดียวกันสามารถมีฟิลด์ต่างกันได้ ทำให้เก็บข้อมูลที่หลากหลายได้โดยไม่ต้องเปลี่ยนแปลงโครงสร้าง
สรุป: MongoDB เก็บข้อมูลเป็นเอกสาร BSON ใน collection โดยเทียบได้กับ row ใน table ของ RDBMS แต่ยืดหยุ่นกว่าเพราะแต่ละเอกสารมีฟิลด์ต่างกันได้
📝 แบบฝึกหัด
- คำว่า table, row, column ใน RDBMS เทียบกับคำใดใน MongoDB?
- ใน RDBMS เราเขียน
SELECT * FROM productsจงเขียนคำสั่งเทียบเท่าใน MongoDB - ทำไมจึงกล่าวว่า “แต่ละเอกสารใน collection เดียวกันมีฟิลด์ต่างกันได้” เป็นจุดเด่นของ MongoDB?
6. เครื่องมือ — MongoDB Community Server และ Compass#
ในบทความ RDBMS เราใช้ MongoDB Community Server (เวอร์ชันฟรี ใช้งานได้เต็มที่) แล้วใช้ MongoDB Compass เป็น GUI จัดการฐานข้อมูล คล้าย phpMyAdmin
ดาวน์โหลดและติดตั้ง MongoDB Community Server#
- เปิดหน้าดาวน์โหลด: https://www.mongodb.com/try/download/community ↗
- เลือก เวอร์ชันล่าสุด, ระบบปฏิบัติการ (Windows / macOS / Linux) และ รูปแบบตัวติดตั้ง (เช่น
.msiสำหรับ Windows,.tgz/.zipสำหรับ macOS/Linux) - ดาวน์โหลดแล้วรันตัวติดตั้ง — ระหว่างติดตั้งบน Windows แนะนำให้เลือก “Install MongoDB as a Service” (รันเป็นบริการเริ่มต้นอัตโนมัติทุกครั้งที่เปิดเครื่อง) และติดตั้ง MongoDB Compass ไปพร้อมกันได้เลย
เมื่อติดตั้งเสร็จ MongoDB จะทำงานเป็น background service คอยรับการเชื่อมต่อที่ port 27017 (ค่าเริ่มต้น)

MongoDB Compass — GUI จัดการฐานข้อมูล#
MongoDB Compass เป็น GUI สำหรับจัดการฐานข้อมูลคล้าย phpMyAdmin (ติดตั้งไปพร้อม Community Server ได้ หรือดาวน์โหลดแยกจากเว็บ MongoDB) เปิด Compass แล้ววาง connection string นี้เพื่อเชื่อมต่อกับเซิร์ฟเวอร์บนเครื่องของคุณ:
mongodb://localhost:27017จากนั้นจะเห็น database, collection และเอกสารในรูปแบบกราฟิก สามารถเพิ่ม แก้ไข ลบ และรัน query ได้ผ่าน GUI โดยไม่ต้องใช้ command line

ตัวอย่างคำสั่งในหัวข้อต่อ ๆ ไป เขียนในรูปแบบ mongosh (MongoDB Shell) ซึ่งเป็น JavaScript รันคำสั่งได้ทั้งใน Compass หรือ terminal

7. Database, Collection, Document — สร้างและเพิ่มข้อมูล#
เราจะใช้ฐานข้อมูลร้านค้าชื่อ shop และ collection ชื่อ products สมมติเก็บสินค้าที่มีรายละเอียดซ้อนกัน (specs, tags) ซึ่งเป็นจุดเด่นของ document database
สร้าง database และเพิ่มเอกสารเดียว (insertOne)#
ใน mongosh ใช้คำสั่ง use เพื่อสลับไปยัง database (สร้างอัตโนมัติเมื่อเพิ่มข้อมูลครั้งแรก) แล้วใช้ insertOne เพื่อเพิ่มเอกสาร
use shop
db.products.insertOne({
name: "Wireless Mouse",
price: 590,
category: "Accessories",
stock: 25,
rating: 4.5,
tags: ["wireless", "ergonomic"],
specs: { color: "black", battery: "AAA" }
})javascript
สังเกตว่าเราไม่ต้องสร้างตารางหรือกำหนด schema ล่วงหน้า — เพิ่มเอกสารเข้าไปได้เลย MongoDB จะสร้าง _id (primary key) ให้อัตโนมัติหากไม่ระบุ ตรวจสอบผลลัพธ์ได้ตามรูป

เพิ่มหลายเอกสาร (insertMany)#
db.products.insertMany([
{ name: "Mechanical Keyboard", price: 1890, category: "Accessories", stock: 12, rating: 4.8 },
{ name: "USB-C Hub", price: 750, category: "Accessories", stock: 0, rating: 4.2 },
{ name: "4K Monitor", price: 8500, category: "Displays", stock: 8, rating: 4.7 },
{ name: "Laptop Stand", price: 690, category: "Accessories", stock: 30, rating: 4.0 },
{ name: "Webcam HD", price: 1200, category: "Electronics", stock: 15, rating: 4.3 },
{ name: "Bluetooth Speaker", price: 1450, category: "Electronics", stock: 18, rating: 4.6 },
{ name: "Desk Lamp", price: 560, category: "Accessories", stock: 0, rating: 3.9 }
])javascriptข้อมูลตัวอย่างนี้จะใช้สำหรับตัวอย่าง query ในหัวข้อถัดไป — สังเกตว่าสินค้าบางตัว (เช่น Wireless Mouse ตัวแรก) มี tags และ specs ส่วนตัวอื่นไม่มี นี่คือความยืดหยุ่นของ schema ที่ RDBMS ทำได้ยาก
สรุป:
use <db>เลือก database,db.<collection>.insertOne()/insertMany()เพิ่มเอกสาร MongoDB สร้าง_idให้อัตโนมัติ และยอมรับเอกสารที่มีฟิลด์ต่างกันใน collection เดียวกัน
📝 แบบฝึกหัด
- จงเขียนคำสั่ง
insertOneเพิ่มสินค้า “USB Cable” ราคา 199 หมวด Accessories stock 50 rating 4.1 - หากต้องการเพิ่มสินค้า 3 ชนิดในคำสั่งเดียว ต้องใช้
insertOneหรือinsertMany? เพราะอะไร? - ถ้าไม่ระบุฟิลด์
_idเอง MongoDB จะทำอย่างไร?
8. find() — ดึงข้อมูล#
คำสั่ง find() ของ MongoDB เทียบเท่า SELECT ของ SQL ใช้ดึงเอกสารจาก collection
ดึงทุกเอกสาร#
db.products.find()javascriptเทียบเท่า SELECT * FROM products ใน SQL เพิ่ม .pretty() ถ้ารันใน shell เก่าเพื่อให้ผลลัพธ์อ่านง่าย (mongosh ปัจจุบันจัดรูปแบบให้อัตโนมัติ)

ดึงเฉพาะฟิลด์ที่ต้องการ (Projection)#
เหมือนการเลือกคอลัมน์ใน SQL กำหนด 1 สำหรับฟิลด์ที่ต้องการแสดง และ 0 สำหรับฟิลด์ที่ต้องการซ่อน
// แสดงเฉพาะ name และ price (ซ่อน _id)
db.products.find({}, { name: 1, price: 1, _id: 0 })javascriptผลลัพธ์:
| name | price |
|---|---|
| Wireless Mouse | 590 |
| Mechanical Keyboard | 1890 |
| USB-C Hub | 750 |
| 4K Monitor | 8500 |
| Laptop Stand | 690 |
| Webcam HD | 1200 |
| Bluetooth Speaker | 1450 |
| Desk Lamp | 560 |
เคล็ดลับ:
_idถูกส่งกลับมาเสมอ หากไม่ต้องการให้ระบุ_id: 0อย่างชัดเจน
💡 ใช้ผ่าน UI ก็ได้: นอกจากพิมพ์คำสั่งใน mongosh (MongoDB Shell) แล้ว คุณยังสามารถรัน
findผ่าน MongoDB Compass ซึ่งเป็น GUI ได้เช่นกัน ใน Compass มีช่องกรอก 2 ช่องที่ตรงกับอาร์กิวเมนต์ 2 ตัวของfind()คือ
- Filter — ใส่เงื่อนไขกรอง (อาร์กิวเมนต์แรก) ที่นี่คือ
{}หมายถึงไม่กรอง เอาทุกเอกสาร- Project — ใส่ projection ที่จะเลือกฟิลด์ (อาร์กิวเมนต์ที่สอง) ที่นี่คือ
{ name: 1, price: 1, _id: 0 }กรอกเสร็จแล้วกดปุ่ม Find ผลลัพธ์จะแสดงเป็นตารางที่อ่านง่าย ด้านล่างคือการกรอกคำสั่ง
db.products.find({}, { name: 1, price: 1, _id: 0 })ผ่าน Compass — สังเกตว่าเราต้องใส่{ name: 1, price: 1, _id: 0 }ลงในช่อง Project เพื่อให้แสดงเฉพาะฟิลด์ name และ price และซ่อน_id

📝 แบบฝึกหัด
- จงเขียน
findที่ดึงเฉพาะฟิลด์ name และ rating จากทุกสินค้า (ซ่อน_id) - คำสั่ง
db.products.find({})จะคืนผลลัพธ์เท่ากับคำสั่ง SQL ใด? - จะซ่อนฟิลด์
_idออกจากผลลัพธ์ต้องกำหนดค่าอะไรในส่วน projection?
9. Query Operators — กรองข้อมูลด้วยเงื่อนไข#
การกรองใน MongoDB ทำได้โดยใส่เงื่อนไขใน find() และใช้ query operator ที่ขึ้นต้นด้วย $
กรองค่าตรงตัว (เทียบเท่า WHERE column = value)#
db.products.find({ category: "Accessories" })javascriptคืนเฉพาะสินค้าหมวด Accessories (5 รายการ)

เปรียบเทียบตัวเลขด้วย lt, lte#
| Operator | ความหมาย | SQL เทียบเท่า |
|---|---|---|
$gt | มากกว่า | > |
$gte | มากกว่าหรือเท่ากับ | >= |
$lt | น้อยกว่า | < |
$lte | น้อยกว่าหรือเท่ากับ | <= |
$ne | ไม่เท่ากับ | != |
$in | อยู่ในชุดที่กำหนด | IN (...) |
// ราคามากกว่า 1000
db.products.find({ price: { $gt: 1000 } })javascriptผลลัพธ์:
| name | price |
|---|---|
| Mechanical Keyboard | 1890 |
| 4K Monitor | 8500 |
| Webcam HD | 1200 |
| Bluetooth Speaker | 1450 |

หลายเงื่อนไข — ค่าเริ่มต้นคือ AND#
เมื่อใส่หลายฟิลด์ในเงื่อนไขเดียว MongoDB ถือว่าต้องเป็นจริงทั้งคู่ (AND) โดยอัตโนมัติ
// หมวด Accessories และ stock > 10
db.products.find({ category: "Accessories", stock: { $gt: 10 } })javascriptผลลัพธ์:
| name | category | stock |
|---|---|---|
| Wireless Mouse | Accessories | 25 |
| Mechanical Keyboard | Accessories | 12 |
| Laptop Stand | Accessories | 30 |
(USB-C Hub และ Desk Lamp ถูกตัดเพราะ stock เป็น 0)
ใช้ $or สำหรับ “หรือ”#
db.products.find({
$or: [
{ category: "Displays" },
{ rating: { $gte: 4.6 } }
]
})javascriptคืนสินค้าที่เป็นหมวด Displays หรือ rating ≥ 4.6 — ได้ 4K Monitor (Displays), Mechanical Keyboard (4.8), Bluetooth Speaker (4.6)
ใช้ $in สำหรับชุดค่า#
// หมวดเป็น Displays หรือ Electronics
db.products.find({ category: { $in: ["Displays", "Electronics"] } })javascriptสรุป: MongoDB กรองด้วยเงื่อนไขใน
find()หลายฟิลด์คือ AND โดยปริยาย,$orสำหรับหรือ,$gt/$lt/...สำหรับเปรียบเทียบ และ$inสำหรับชุดค่า
📝 แบบฝึกหัด
- จงเขียน query หาสินค้าที่ rating ≥ 4.5 และ stock > 0 (หลายฟิลด์ในเงื่อนไขเดียว)
- จงเขียน query หาสินค้าหมวด Displays หรือ Electronics โดยใช้
$in - จงเขียน query หาสินค้าที่ ราคา < 700 หรือ rating > 4.7 โดยใช้
$or - จะเขียน query หา “สินค้าที่ stock ไม่เท่ากับ 0” ด้วย operator ใด?
10. sort, limit และ count#
เรียงลำดับ — sort()#
ใช้ 1 สำหรับน้อยไปมาก (ASC) และ -1 สำหรับมากไปน้อย (DESC) เหมือน ORDER BY ใน SQL
// เรียงราคาจากมากไปน้อย
db.products.find().sort({ price: -1 })javascriptผลลัพธ์ (ส่วนบน):
| name | price |
|---|---|
| 4K Monitor | 8500 |
| Mechanical Keyboard | 1890 |
| Bluetooth Speaker | 1450 |
| Webcam HD | 1200 |
จำกัดจำนวน — limit()#
ใช้ร่วมกับ sort() เพื่อดึง “top N” เหมือน LIMIT ใน SQL
// สินค้า 3 อันดับที่แพงที่สุด
db.products.find().sort({ price: -1 }).limit(3)javascriptผลลัพธ์: 4K Monitor, Mechanical Keyboard, Bluetooth Speaker
นับจำนวน — countDocuments()#
// นับสินค้าในหมวด Accessories ที่ stock > 10
db.products.countDocuments({ category: "Accessories", stock: { $gt: 10 } })javascriptผลลัพธ์: 3
สรุป:
sort()เรียงลำดับ (1/-1),limit()จำกัดจำนวน,countDocuments()นับจำนวนเอกสารที่ตรงเงื่อนไข
📝 แบบฝึกหัด
- จงเขียน query หา สินค้า 3 อันดับที่ rating สูงที่สุด (ใช้
sort+limit) - จงเขียนคำสั่ง นับสินค้าที่ stock = 0 (ผลลัพธ์ที่คาดว่าจะได้คือเท่าใด?)
- ถ้าต้องการเรียงสินค้าตามราคา จากน้อยไปมาก ต้องใช้
1หรือ-1ในsort?
11. Aggregation — จัดกลุ่มและสรุปข้อมูล#
Aggregation Pipeline ของ MongoDB เทียบเท่า GROUP BY รวมถึงการคำนวณ SUM, AVG, COUNT ใน SQL โดยเชื่อมขั้นตอน (stage) หลายขั้นเข้าด้วยกัน
หาค่าเฉลี่ยราคาแยกตามหมวด — $group#
db.products.aggregate([
{
$group: {
_id: "$category",
avgPrice: { $avg: "$price" },
count: { $sum: 1 }
}
}
])javascriptอธิบายแต่ละส่วน:
$group— จัดกลุ่มเอกสารตามฟิลด์ที่กำหนด_id: "$category"— ฟิลด์ที่จะจัดกลุ่ม (ใช้$นำหน้าชื่อฟิลด์)avgPrice: { $avg: "$price" }— คำนวณค่าเฉลี่ยpriceของแต่ละกลุ่ม เก็บในชื่อavgPricecount: { $sum: 1 }— นับจำนวนเอกสารในแต่ละกลุ่ม (บวก 1 ทีละแถว)
ผลลัพธ์:
| _id (category) | avgPrice | count |
|---|---|---|
| Accessories | 896 | 5 |
| Displays | 8500 | 1 |
| Electronics | 1325 | 2 |

Aggregation Operators ที่ใช้บ่อย#
| Operator | ความหมาย | SQL เทียบเท่า |
|---|---|---|
$sum | ผลรวม / นับ ($sum: 1) | SUM() / COUNT() |
$avg | ค่าเฉลี่ย | AVG() |
$min / $max | ค่าต่ำ/สูงสุด | MIN() / MAX() |
// หาราคาสูงสุดและต่ำสุดในแต่ละหมวด
db.products.aggregate([
{
$group: {
_id: "$category",
maxPrice: { $max: "$price" },
minPrice: { $min: "$price" }
}
}
])javascriptสรุป: Aggregation Pipeline จัดกลุ่มและสรุปข้อมูลผ่านหลาย stage เริ่มต้นด้วย
$groupและใช้$avg,$sum,$min,$maxคำนวณ — เทียบเท่าGROUP BYและ aggregate functions ของ SQL
📝 แบบฝึกหัด
- จงเขียน aggregation หา ราคารวม (sum) ของสินค้าแยกตามหมวด โดยตั้งชื่อผลลัพธ์ว่า
totalPrice - จงเขียน aggregation หา rating เฉลี่ยของสินค้าทั้งหมด โดยไม่แบ่งหมวด (คำใบ้: ใช้
_id: null) - ใน
$group, ทำไมต้องมีเครื่องหมาย$นำหน้าชื่อฟิลด์ เช่น"$price"?
12. update — แก้ไขข้อมูล#
updateOne() แก้ไขเอกสารแรกที่ตรงเงื่อนไข, updateMany() แก้ไขทุกเอกสารที่ตรง ใช้ update operator นำหน้าด้วย $
แก้ไขฟิลด์ด้วย $set#
// เปลี่ยนราคา Wireless Mouse
db.products.updateOne(
{ name: "Wireless Mouse" },
{ $set: { price: 690 } }
)javascript- อาร์กิวเมนต์แรก
{ name: "Wireless Mouse" }— เงื่อนไขหาเอกสาร (เหมือนWHERE) - อาร์กิวเมนต์์ที่สอง
{ $set: { price: 690 } }— สิ่งที่จะเปลี่ยน ($setตั้งค่าใหม่)
เพิ่มค่าตัวเลขด้วย $inc#
// เพิ่ม stock ทุกสินค้าหมวด Accessories ขึ้น 5
db.products.updateMany(
{ category: "Accessories" },
{ $inc: { stock: 5 } }
)javascript$inc (increment) เพิ่มค่าตัวเลขตามจำนวนที่กำหนด ใช้ค่าลบเพื่อลดได้
เพิ่มสมาชิกใน array ด้วย $push#
// เพิ่มแท็ก "sale" ให้ Wireless Mouse
db.products.updateOne(
{ name: "Wireless Mouse" },
{ $push: { tags: "sale" } }
)javascript| Operator | การทำงาน |
|---|---|
$set | ตั้งค่าฟิลด์ (สร้างใหม่ถ้ายังไม่มี) |
$inc | เพิ่ม/ลดค่าตัวเลข |
$push | เพิ่มสมาชิกต่อท้าย array |
$unset | ลบฟิลด์ออกจากเอกสาร |
⚠️ คำเตือน: อย่าลืมใส่ update operator (
$set,$incฯลฯ) หากเขียน{ price: 690 }ตรง ๆ MongoDB จะพยายาม แทนที่เอกสารทั้งฉบับ ด้วย{ price: 690 }ซึ่งมักไม่ใช่สิ่งที่ตั้งใจ
สรุป:
updateOne/updateManyแก้ไขเอกสาร โดยอาร์กิวเมนต์แรกคือเงื่อนไข อาร์กิวเมนต์์ที่สองใช้ operator เช่น$set,$inc,$push
📝 แบบฝึกหัด
- จงเขียน
updateOneเปลี่ยน rating ของ “Desk Lamp” เป็น 4.2 (ใช้$set) - จงเขียน
updateManyลด stock ของสินค้าหมวด Electronics ลง 3 (ใช้$incกับค่าลบ) - จงเขียนคำสั่งเพิ่มแท็ก “new” ให้ “Webcam HD” (ใช้
$push) - ถ้าเขียน
db.products.updateOne({ name: "Desk Lamp" }, { price: 700 })โดยไม่ใส่$setจะเกิดอะไรขึ้น?
13. delete — ลบข้อมูล#
deleteOne() ลบเอกสารแรกที่ตรงเงื่อนไข, deleteMany() ลบทุกเอกสารที่ตรง เหมือน DELETE ใน SQL
ลบด้วยเงื่อนไข#
// ลบสินค้าที่ stock เป็น 0 (สินค้าหมด)
db.products.deleteMany({ stock: 0 })javascriptคำสั่งนี้จะลบ USB-C Hub และ Desk Lamp (ทั้งคู่มี stock: 0)
ลบเอกสารเดียว#
db.products.deleteOne({ name: "4K Monitor" })javascript⚠️ คำเตือนสำคัญ: หากใส่เงื่อนไขว่าง
{}จะลบเอกสาร ทั้งหมด ใน collection!javascriptdb.products.deleteMany({}) // ลบทุกเอกสารใน productsให้ตรวจสอบเงื่อนไขเสมอก่อนรัน
deleteMany
สรุป:
deleteOne/deleteManyลบเอกสารตามเงื่อนไข ระวังเงื่อนไขว่าง{}ที่จะลบทุกอย่าง
📝 แบบฝึกหัด
- จงเขียน
deleteManyลบสินค้าที่ stock = 0 — มีกี่รายการที่จะถูกลบ? - จงเขียนคำสั่งลบสินค้า “4K Monitor” เฉพาะเอกสารเดียว
- คำสั่ง
db.products.deleteMany({})ทำอะไร? ควรระวังอะไร?
14. Schema Design — Embed vs Reference#
ใน RDBMS เราแยกข้อมูลเป็นหลายตารางแล้วเชื่อมด้วย foreign key + JOIN แต่ใน MongoDB มีแนวทางออกแบบ 2 แบบหลัก คือ ฝัง (Embed) และ อ้างอิง (Reference)
Embed — ฝังข้อมูลที่เกี่ยวข้องไว้ด้วยกัน#
เหมาะเมื่อข้อมูลถูกอ่านร่วมกันเสมอ และมีจำนวนไม่มาก (one-to-few) เช่นรีวิวสินค้าที่ฝังในเอกสารสินค้า
{
name: "Wireless Mouse",
price: 590,
reviews: [
{ user: "Somchai", stars: 5, comment: "ดีมาก" },
{ user: "Nida", stars: 4, comment: "ใช้งานสะดวก" }
]
}javascriptข้อดี: ดึงข้อมูลครบใน query เดียว ไม่ต้อง JOIN อ่านเร็ว
Reference — เก็บ ID อ้างอิงข้าม collection#
เหมาะเมื่อข้อมูลมีจำนวนมาก ถูกใช้ซ้ำ หรือเปลี่ยนแปลงบ่อย (one-to-many, many-to-many) เช่นคำสั่งซื้อที่อ้างอิงผู้ใช้และสินค้าแยก collection
// collection: orders
{
orderNo: "ORD-001",
userId: ObjectId("..."), // อ้างอิง users
items: [
{ productId: ObjectId("..."), qty: 2 } // อ้างอิง products
]
}javascript
เลือกแบบไหน?#
| เกณฑ์ | แนะนำ |
|---|---|
| ข้อมูลน้อย อ่านร่วมกันเสมอ ไม่ค่อยเปลี่ยน | Embed |
| ข้อมูลมาก ใช้ซ้ำข้ามเอกสาร เปลี่ยนบ่อย | Reference |
| ความสัมพันธ์แบบ one-to-few | Embed |
| ความสัมพันธ์แบบ many-to-many | Reference |
สรุป: MongoDB ให้เลือกฝังหรืออ้างอิงตามลักษณะข้อมูล ฝังเมื่ออ่านร่วมกันและมีไม่มาก อ้างอิงเมื่อมีจำนวนมากหรือใช้ซ้ำ — การออกแบบที่ดีคือหัวใจของการใช้ NoSQL ให้มีประสิทธิภาพ
📝 แบบฝึกหัด
- ข้อมูล “ที่อยู่จัดส่ง” ของผู้ใช้ (บ้านเลขที่ ถนน ตำบล อำเภอ จังหวัด) ควร embed ในเอกสารผู้ใช้ หรือ reference collection แยก? เพราะอะไร?
- ข้อมูล “ความคิดเห็น” ในเว็บบอร์ดที่แต่ละโพสต์มีคอมเมนต์ นับพัน ควร embed หรือ reference? เพราะอะไร?
- จงยกตัวอย่างความสัมพันธ์แบบ one-to-few ที่เหมาะกับการ embed 1 กรณี
15. ตัวอย่าง Prompt สำหรับสร้าง Query ด้วย Generative AI#
สามารถใช้ ChatGPT หรือ Claude ช่วยสร้าง MongoDB query ได้ โดยให้บริบทที่ชัดเจน
Prompt 1 — ค้นหาและกรอง:
collection
productsมีฟิลด์ name, price, category, stock, rating จงเขียน MongoDB query หาสินค้าหมวด Electronics ที่ราคาต่ำกว่า 1500 และ stock มากกว่า 10 เรียงตามราคาน้อยไปมาก
Prompt 2 — Aggregation:
จาก collection
productsที่มีฟิลด์ category และ price จงเขียน MongoDB aggregation หาราคาเฉลี่ยและจำนวนสินค้าแยกตามหมวด เรียงตามราคาเฉลี่ยจากมากไปน้อย
Prompt 3 — สร้างข้อมูลตัวอย่าง:
Generate MongoDB
insertManystatements for aproductscollection with fields name, price, category, stock, and rating, using 10 realistic sample products across categories Electronics, Accessories, and Displays.
เคล็ดลับ: ยิ่งบอกชื่อ collection, ฟิลด์ และสิ่งที่ต้องการชัดเท่าไหร่ query ที่ได้ก็ยิ่งตรงความต้องการมากขึ้น
16. สรุป#
บทความนี้ครอบคลุมพื้นฐาน NoSQL Database และ MongoDB ตั้งแต่แนวคิดไปจนถึงการปฏิบัติ:
- NoSQL — ฐานข้อมูลที่ schema ยืดหยุ่น รองรับข้อมูลปริมาณมหาศาลและรูปแบบหลากหลาย
- JSON — รูปแบบข้อความ key-value ที่เป็นรากฐานของ document database
- ประเภทของ NoSQL — Document, Key-Value, Wide Column, Graph แต่ละแบบเหมาะกับงานต่างกัน
- MongoDB — Document database ที่เก็บข้อมูลเป็น BSON, เทียบ table/row กับ collection/document
- Community Server & Compass — ติดตั้งฐานข้อมูลบนเครื่องและจัดการผ่าน GUI
- CRUD —
insertOne/insertMany,find,updateOne/updateMany,deleteOne/deleteMany - Query operators —
$gt,$lt,$or,$inสำหรับกรองข้อมูล - Aggregation —
$groupกับ$avg,$sum,$max,$minสำหรับสรุปข้อมูล - Schema design — Embed vs Reference เลือกตามลักษณะความสัมพันธ์
แต่ละหัวข้อมี 📝 แบบฝึกหัด ให้ฝึกทบทวน เมื่อเข้าใจพื้นฐานเหล่านี้แล้ว คุณจะสามารถออกแบบและจัดการฐานข้อมูล NoSQL สำหรับแอปพลิเคชันที่ต้องการความยืดหยุ่นและความเร็ว พร้อมต่อยอดสู่การพัฒนา API, real-time application และระบบที่รองรับข้อมูลปริมาณมหาศาล