
MongoDB คือฐานข้อมูลแบบ NoSQL ที่ไม่ได้เก็บข้อมูลเป็นตารางแบบ Excel แต่เก็บเป็น "การ์ด" ทีละใบ เรียกว่า Document หน้าตาคล้าย JSON แต่ละใบมีช่องไม่เท่ากันได้ ข้อมูลที่ใช้ด้วยกันจึงเก็บรวมไว้ในใบเดียวได้เลย
คู่มือ MongoDB สำหรับมือใหม่นี้จะเทียบให้เห็นภาพก่อนว่าการ์ดต่างจากตาราง SQL ยังไง แล้วพาเปิด MongoDB ในเครื่องด้วย Docker ลองเพิ่ม ค้น แก้ และลบข้อมูลทีละคำสั่ง พร้อมกับดักที่มือใหม่เจอบ่อย และวิธีเลือกว่างานไหนควรใช้ MongoDB งานไหนควรใช้ SQL ไม่ต้องรู้ SQL มาก่อนก็ทำตามได้
ทุกคำสั่งในบทความนี้รันจริงแล้ว ทดสอบกับ MongoDB 9.0 (รุ่นปัจจุบันตามหน้าเอกสาร ณ 1 พ.ย. 2026) ผ่าน Docker และ mongosh 2.6 ผลลัพธ์ที่แสดงคือผลจริง ยกเว้นรหัส ObjectId ที่จะไม่เหมือนกันในเครื่องคุณ
จบบทความนี้คุณจะ:
- อธิบายได้ว่า MongoDB คืออะไร และต่างจากฐานข้อมูลแบบตาราง (SQL) ยังไง
- เข้าใจคำว่า Database, Collection และ Document ด้วยภาพตู้เอกสาร
- เปิด MongoDB ในเครื่องด้วย Docker และต่อเข้าไปด้วย mongosh
- เพิ่ม ค้น แก้ และลบข้อมูล (CRUD) ได้ด้วยตัวเอง รวมถึงข้อมูลที่ซ้อนกัน
- รู้กับดักที่มือใหม่เจอบ่อย และเลือกได้ว่างานไหนควรใช้ MongoDB หรือ SQL
MongoDB คืออะไร ต่างจาก SQL ยังไง
ฐานข้อมูลแบบตาราง (SQL) เหมือนไฟล์ Excel ที่กำหนดหัวคอลัมน์ไว้ตั้งแต่แรก ทุกแถวต้องมีช่องเหมือนกัน
| id | ชื่อ | อายุ |
|---|---|---|
| 1 | เอ | 20 |
| 2 | บี | 25 |
ถ้าอยากเก็บไอจีของบีเพิ่ม ต้องเพิ่มคอลัมน์ให้ทั้งตาราง แล้วแถวของเอก็มีช่องว่างโผล่มา และถ้าคนหนึ่งมีหลายที่อยู่ ต้องสร้างอีกตารางแล้วโยงกลับด้วย id
MongoDB ไม่มีตาราง ข้อมูลหนึ่งชิ้นคือการ์ดหนึ่งใบ แต่ละใบมีช่องไม่เท่ากันได้ ตัวอย่างการ์ด 2 ใบในลิ้นชักเดียวกัน
{ name: "เอ", age: 20, phone: "081-xxx" }
{ name: "บี", age: 25, instagram: "@bee" }| เรื่อง | ตาราง (SQL) | การ์ด (MongoDB) |
|---|---|---|
| รูปร่าง | ทุกแถวช่องเท่ากัน | แต่ละใบช่องไม่เท่ากันได้ |
| เพิ่มช่องใหม่ | แก้โครงสร้างทั้งตาราง | ใส่ในใบนั้นได้เลย |
| ข้อมูลหลายชิ้น เช่น ที่อยู่ 2 ที่ | แยกอีกตารางแล้ว JOIN | ซ้อนไว้ในการ์ดใบเดียว |
| ภาษาที่ใช้ค้น | SQL | เงื่อนไขเป็นก้อนแบบ JSON |
สรุปสั้นๆ ตารางคือทุกแถวหน้าตาเหมือนกัน ส่วนการ์ดคือแต่ละใบเขียนต่างกันได้
ศัพท์ MongoDB ที่ต้องรู้
จำแค่ 3 คำหลักก่อน ตู้ (Database) → ลิ้นชัก (Collection) → การ์ด (Document)

| คำ | ความหมายแบบมือใหม่ | เทียบฝั่ง SQL |
|---|---|---|
| Database | กลุ่มข้อมูลของแอปหนึ่งตัว (ตู้) | Database |
| Collection | กลุ่มการ์ดเรื่องเดียวกัน เช่น users (ลิ้นชัก) | Table |
| Document | ข้อมูลหนึ่งชิ้น (การ์ดหนึ่งใบ) | Row (แถว) |
| Field | หัวข้อบนการ์ด เช่น name, age | Column |
| _id | รหัสประจำการ์ด MongoDB ใส่ให้เองถ้าเราไม่ใส่ | Primary key |
| JSON / BSON | รูปแบบข้อมูล {ชื่อ: ค่า} MongoDB เก็บจริงเป็น BSON | - |
| mongosh | โปรแกรมพิมพ์คำสั่งคุยกับ MongoDB | psql, mysql |
| Atlas | MongoDB บนคลาวด์ของบริษัท MongoDB | - |
| Query | คำสั่งค้นหา | SELECT |
เอกสารของ MongoDB อธิบายว่า document คือหน่วยพื้นฐานของข้อมูลใน MongoDB และเก็บจริงในรูปแบบ BSON ซึ่งเป็น JSON แบบไบนารีที่มีชนิดข้อมูลมากกว่า เช่น วันที่ และตัวเลขหลายแบบ
หน้าตา Document และชนิดข้อมูลที่ใส่ได้
ทุกบรรทัดในการ์ดคือ ช่อง: ค่า ค่าที่ใส่ได้มีหลายแบบ รวมถึงรายการและการ์ดซ้อนในการ์ด
{
_id: ObjectId("..."),
name: "เอ",
age: 20,
active: true,
tags: ["news", "sports"],
address: { city: "เชียงใหม่" },
birth: new Date("2000-01-31")
}| ชนิด | ตัวอย่าง |
|---|---|
| ข้อความ | name: "เอ" |
| ตัวเลข | age: 20 |
| จริง / เท็จ | active: true |
| รายการ (array) | tags: ["news", "sports"] |
| การ์ดซ้อน (embedded document) | address: { city: "เชียงใหม่" } |
| วันที่ | birth: new Date("2000-01-31") |
สังเกตว่า tags เก็บได้หลายค่าในช่องเดียว ถ้าเป็นตาราง SQL ต้องแยกอีกตาราง นี่คือข้อดีที่ชัดที่สุดของ MongoDB ข้อมูลที่ใช้ด้วยกันอยู่ในการ์ดใบเดียว ดึงทีเดียวได้ครบ
ใช้ MongoDB ฟรี: ในเครื่องด้วย Docker หรือ Atlas
มีสองทางให้เลือก ทั้งสองทางฟรี
| เรื่อง | ทาง 1: ในเครื่องด้วย Docker | ทาง 2: MongoDB Atlas แพ็กเกจ Free |
|---|---|---|
| ต้องมี | Docker Desktop | อีเมลสำหรับสมัครบัญชี |
| ค่าใช้จ่าย | ฟรี | "$0/hour" และ "Free forever" ตามหน้า Pricing |
| พื้นที่ | ตามดิสก์เครื่องเรา | 512 MB |
| ข้อมูลอยู่ที่ | เครื่องเรา | คลาวด์ของ MongoDB |
| เหมาะกับ | ฝึกโดยไม่ต้องสมัครอะไร | อยากต่อจากแอปที่อยู่บนอินเทอร์เน็ตจริง |
บทความนี้พาทำทาง 1 เพราะไม่ต้องสมัครบัญชี คำสั่งเพิ่ม ค้น แก้ ลบในหัวข้อถัดไปใช้ได้เหมือนกันทั้งสองทาง ถ้าเลือก Atlas ให้ทำตามหัวข้อ Get Started with Atlas ในเอกสารทางการ แล้วเอา connection string ที่ได้มาใช้กับ mongosh
ติดตั้ง MongoDB ด้วย Docker
ลง Docker Desktop แล้วเปิดโปรแกรมทิ้งไว้ เช็กว่าพร้อม
docker --versionโหลดและเปิด MongoDB ด้วยคำสั่งจากหน้า Install MongoDB Community with Docker ของเอกสารทางการ
docker pull mongodb/mongodb-community-server:9.0-ubi9-slim
docker run --name mongodb -p 27017:27017 -d mongodb/mongodb-community-server:9.0-ubi9-slim--name mongodbตั้งชื่อกล่อง (container)-p 27017:27017เปิดพอร์ต 27017 ให้เครื่องเราต่อเข้าไปได้-dให้รันอยู่เบื้องหลัง
เช็กว่าเปิดแล้ว
docker ps... mongodb/mongodb-community-server:9.0-ubi9-slim ... Up 6 seconds ... 0.0.0.0:27017->27017/tcp mongodbต่อเข้า MongoDB ด้วย mongosh
มีสองวิธี เลือกวิธีไหนก็ได้
วิธีที่ 1 ใช้ mongosh ที่มากับกล่อง ไม่ต้องติดตั้งอะไรเพิ่ม (เราเช็กแล้วว่าอิมเมจนี้มี mongosh 2.6 อยู่ข้างใน)
docker exec -it mongodb mongoshวิธีที่ 2 ลง mongosh ในเครื่อง จากหน้าดาวน์โหลด mongosh แล้วปิดเปิดหน้าต่างคำสั่งใหม่ จากนั้นต่อด้วย
mongosh --port 27017ขึ้นบรรทัดรอคำสั่ง test> แปลว่าต่อติดแล้ว พิมพ์คำสั่งในหัวข้อถัดไปต่อที่นี่ได้เลย ออกด้วย exit
เพิ่ม ค้น แก้ ลบข้อมูลใน MongoDB
เลือกตู้ แล้วเพิ่มการ์ดใบแรก
use devkubswitched to db devkubตู้ชื่อ devkub ยังไม่มีก็ไม่เป็นไร MongoDB สร้างให้เองตอนใส่การ์ดใบแรก ลิ้นชักก็เหมือนกัน
db.users.insertOne({ name: "เอ", age: 20, phone: "081-xxx" }){
acknowledged: true,
insertedId: ObjectId('6ae64be75708d744a9284d0c')
}เพิ่มทีละหลายใบ ช่องไม่เท่ากันก็ได้
db.users.insertMany([
{ name: "บี", age: 25, instagram: "@bee" },
{ name: "ซี", age: 31 }
]){
acknowledged: true,
insertedIds: {
'0': ObjectId('6ae64be75708d744a9284d0d'),
'1': ObjectId('6ae64be75708d744a9284d0e')
}
}ดูการ์ดทั้งหมดในลิ้นชัก
db.users.find()[
{ _id: ObjectId('...'), name: 'เอ', age: 20, phone: '081-xxx' },
{ _id: ObjectId('...'), name: 'บี', age: 25, instagram: '@bee' },
{ _id: ObjectId('...'), name: 'ซี', age: 31 }
]เห็นการ์ด 3 ใบ แต่ละใบมี _id ที่ MongoDB ใส่ให้ และช่องไม่เท่ากัน
ค้นหาแบบมีเงื่อนไข
| อยากได้ | พิมพ์ | ได้การ์ดของ |
|---|---|---|
| ชื่อเท่ากับบี | db.users.find({ name: "บี" }) | บี |
| อายุมากกว่า 21 | db.users.find({ age: { $gt: 21 } }) | บี, ซี |
| อายุน้อยกว่า 21 | db.users.find({ age: { $lt: 21 } }) | เอ |
| มีช่อง instagram | db.users.find({ instagram: { $exists: true } }) | บี |
| นับจำนวน | db.users.countDocuments() | ได้เลข 3 |
$gt คือมากกว่า $lt คือน้อยกว่า $gte และ $lte คือมากกว่าหรือเท่ากับ และน้อยกว่าหรือเท่ากับ
แก้การ์ด
db.users.updateOne(
{ name: "ซี" },
{ $set: { age: 32, city: "ขอนแก่น" } }
){
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}$set แก้หรือเพิ่มเฉพาะช่องที่บอก ช่องอื่นอยู่เหมือนเดิม matchedCount: 1 แปลว่าเจอการ์ด 1 ใบ และ modifiedCount: 1 แปลว่าแก้แล้ว 1 ใบ
ลบการ์ด
db.users.deleteOne({ name: "เอ" }){ acknowledged: true, deletedCount: 1 }ระวัง deleteMany ที่เงื่อนไขว่าง
db.users.deleteMany({})ลบการ์ด ทุกใบ ในลิ้นชัก เพราะเงื่อนไขว่างแปลว่าตรงกับทุกใบ ก่อนลบให้ลองใช้findกับเงื่อนไขเดียวกันดูก่อนเสมอว่าจะโดนการ์ดใบไหนบ้าง
ซ้อนข้อมูลในการ์ดใบเดียว และกับดัก age กับ Age
ซ้อนข้อมูล
คนหนึ่งมีหลายที่อยู่ ใส่เป็นรายการของการ์ดซ้อนไว้ในใบเดียวได้เลย
db.users.insertOne({
name: "ดี",
addresses: [
{ type: "บ้าน", city: "เชียงใหม่" },
{ type: "ที่ทำงาน", city: "กรุงเทพ" }
]
})ค้นลงไปในการ์ดซ้อนด้วยจุด .
db.users.find({ "addresses.city": "เชียงใหม่" })ได้การ์ดของดีกลับมา ถ้าเป็นตาราง SQL ต้อง JOIN สองตารางถึงจะได้ผลแบบนี้
กับดัก: age กับ Age
ลองใส่การ์ดที่พิมพ์ชื่อช่องเป็นตัวพิมพ์ใหญ่ แล้วค้นอายุตามปกติ
db.users.insertOne({ name: "อี", Age: 28 })
db.users.find({ age: { $gt: 21 } })ผลลัพธ์ไม่มีการ์ดของอีเลย ทั้งที่อายุ 28 เพราะ MongoDB ถือว่า age กับ Age เป็นคนละช่อง และไม่เตือนอะไรตอนใส่

ความยืดหยุ่นของ MongoDB แปลว่าใส่อะไรก็ได้ ซึ่งก็แปลว่าใส่ผิดก็ได้เหมือนกัน วิธีกันมีสามระดับ
| ระดับ | ทำแบบนี้ |
|---|---|
| ตั้งกติกาชื่อช่อง | ทั้งทีมใช้ตัวพิมพ์เล็กหมด เช่น age, created_at |
| ให้โค้ดเช็กก่อนใส่ | ใช้ไลบรารีกำหนดรูปร่างข้อมูล เช่น Mongoose ใน Node.js |
| ให้ฐานข้อมูลเช็ก | ใช้ Schema Validation ของ MongoDB (ดูในเอกสารหัวข้อนี้) |
ควรเลือก MongoDB หรือ SQL
ไม่มีตัวไหนดีที่สุด มีแต่ตัวที่เหมาะกับงาน แนวทางคร่าวๆ เป็นแบบนี้
| งานแบบนี้ | เอนไปทาง |
|---|---|
| ข้อมูลแต่ละชิ้นรูปร่างไม่เหมือนกัน เช่น สินค้าหลายประเภท | MongoDB |
| ข้อมูลที่ใช้ด้วยกันอยู่เป็นก้อนเดียว เช่น โปรไฟล์กับที่อยู่ | MongoDB |
| รูปร่างข้อมูลยังเปลี่ยนบ่อย กำลังทำต้นแบบ | MongoDB |
| เงินและบัญชี ที่ข้อมูลโยงกันหลายตาราง | SQL |
| ต้องทำรายงานไขว้หลายตารางบ่อยๆ | SQL |
ตารางนี้เป็นแนวทางทั่วไปจากความเห็นของเรา MongoDB ทำ transaction ได้ และฐานข้อมูล SQL บางตัวก็เก็บ JSON ได้ ให้ดูงานจริงของคุณประกอบด้วย ถ้าอยากลองฝั่ง SQL ต่อ อ่านบทความเริ่มต้นใช้ Supabase ซึ่งเป็น PostgreSQL หรือลองแล็บ PostgreSQL ใน Docker แบบเดียวกันในบทความคอขวดฐานข้อมูล
แบบฝึกและแก้ปัญหา
ลองทำ 5 ข้อนี้ให้ครบ
| ข้อ | ลองทำ | ควรได้ |
|---|---|---|
| 1 | เพิ่มการ์ดตัวเองลงลิ้นชัก users มีช่อง name, age และงานอดิเรกเป็นรายการ | find() เห็นการ์ดของคุณ |
| 2 | ค้นคนที่อายุ 25 ขึ้นไป | ใช้ $gte: 25 |
| 3 | สร้างลิ้นชักใหม่ products ใส่สินค้า 2 ชิ้นที่ช่องต่างกัน (เสื้อมีไซซ์ หูฟังมีแบต) | show collections เห็น products กับ users |
| 4 | แก้การ์ดของอี เพิ่มช่อง age ตัวเล็กให้ถูก | ค้น age มากกว่า 21 แล้วเจออี |
| 5 | นับจำนวนการ์ดก่อนและหลังลบ 1 ใบ | ตัวเลขลดลง 1 |
ถ้าเจอปัญหา ดูตารางนี้
| อาการ | น่าจะเป็นเพราะ | ทำยังไง |
|---|---|---|
| docker: command not found | ยังไม่ลง Docker หรือยังไม่เปิด Docker Desktop | เปิด Docker Desktop รอจนขึ้นว่า running |
| port is already allocated | มีโปรแกรมอื่นใช้ 27017 อยู่ | ใช้ -p 27018:27017 แล้วต่อด้วย mongosh --port 27018 |
| The container name "/mongodb" is already in use | เคยสร้างกล่องชื่อนี้แล้ว | ใช้ docker start mongodb แทน docker run |
| mongosh ไม่รู้จักคำสั่ง | ยังไม่ลง mongosh หรือยังไม่เปิดหน้าต่างใหม่ | ใช้วิธี docker exec -it mongodb mongosh แทน |
| MongoNetworkError หรือ ECONNREFUSED | กล่อง mongodb ไม่ได้รันอยู่ | docker ps ดูก่อน แล้ว docker start mongodb |
| find() แล้วว่าง | อยู่ผิดตู้ หรือพิมพ์ชื่อลิ้นชักผิด | db ดูชื่อตู้ และ show collections ดูชื่อลิ้นชัก |
| SyntaxError ใน mongosh | ลืมปิดวงเล็บหรือเครื่องหมายคำพูด | กด Ctrl + C แล้วพิมพ์ใหม่ |
เลิกใช้และลบ MongoDB ออก
ออกจาก mongosh ด้วย exit แล้วหยุดและลบกล่อง
docker stop mongodb
docker rm mongodbstop คือปิดกล่อง ส่วน rm คือลบกล่องทิ้ง ข้อมูลในกล่องหายไปด้วย ถ้าอยากเก็บข้อมูลไว้ใช้ต่อ ใช้แค่ stop แล้วเปิดใหม่ด้วย docker start mongodb และถ้าอยากคืนพื้นที่ดิสก์ ลบอิมเมจด้วย docker rmi mongodb/mongodb-community-server:9.0-ubi9-slim
สรุป
- MongoDB คือฐานข้อมูลแบบ NoSQL ที่เก็บข้อมูลเป็น Document (การ์ด) หน้าตาคล้าย JSON แต่ละใบมีช่องไม่เท่ากันได้
- จำสามคำ ตู้ (Database) → ลิ้นชัก (Collection) → การ์ด (Document)
- เปิด MongoDB ในเครื่องฟรีด้วย Docker หรือใช้ Atlas แพ็กเกจ Free บนคลาวด์ (512 MB)
insertOne/find/updateOne/deleteOneคือเพิ่ม ค้น แก้ ลบ- ชื่อช่องตัวพิมพ์ใหญ่เล็กต่างกันคือคนละช่อง ยืดหยุ่นแปลว่าต้องมีวินัย
- งานที่ข้อมูลรูปร่างไม่แน่นอนเหมาะกับ MongoDB ส่วนงานเงินที่โยงกันหลายตารางเหมาะกับ SQL
| อยากทำ | พิมพ์ใน mongosh |
|---|---|
| เลือกตู้ | use devkub |
| ดูตู้ / ลิ้นชักทั้งหมด | show dbs / show collections |
| เพิ่ม 1 ใบ / หลายใบ | insertOne({...}) / insertMany([...]) |
| ดูทั้งหมด | db.users.find() |
| ค้นแบบมีเงื่อนไข | db.users.find({ age: { $gt: 21 } }) |
| นับ | db.users.countDocuments() |
| แก้ | db.users.updateOne({ name: "ซี" }, { $set: { age: 32 } }) |
| ลบ | db.users.deleteOne({ name: "เอ" }) |
อ่านต่อจากเอกสารทางการ
พร้อมแล้วก็ไปทำ Quiz ท้ายบทด้านล่างเพื่อรับ XP ได้เลยครับ