หน้าแรก / บทความ / สร้างเว็บ

MongoDB คืออะไร? สอนใช้ MongoDB สำหรับมือใหม่ ตั้งแต่ติดตั้งด้วย Docker จนเพิ่ม ค้น แก้ ลบข้อมูล

MongoDB คือฐานข้อมูล NoSQL ที่เก็บข้อมูลเป็น Document หน้าตาคล้าย JSON เทียบกับตาราง SQL ให้เห็นภาพ แล้วเปิด MongoDB ด้วย Docker ลองเพิ่ม ค้น แก้ ลบเองทีละคำสั่ง พร้อมกับดักที่มือใหม่เจอบ่อย

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 ใบในลิ้นชักเดียวกัน

การ์ด 2 ใบ ช่องไม่เท่ากัน
{ name: "เอ", age: 20, phone: "081-xxx" }
{ name: "บี", age: 25, instagram: "@bee" }
เรื่องตาราง (SQL)การ์ด (MongoDB)
รูปร่างทุกแถวช่องเท่ากันแต่ละใบช่องไม่เท่ากันได้
เพิ่มช่องใหม่แก้โครงสร้างทั้งตารางใส่ในใบนั้นได้เลย
ข้อมูลหลายชิ้น เช่น ที่อยู่ 2 ที่แยกอีกตารางแล้ว JOINซ้อนไว้ในการ์ดใบเดียว
ภาษาที่ใช้ค้นSQLเงื่อนไขเป็นก้อนแบบ JSON

สรุปสั้นๆ ตารางคือทุกแถวหน้าตาเหมือนกัน ส่วนการ์ดคือแต่ละใบเขียนต่างกันได้

ศัพท์ MongoDB ที่ต้องรู้

จำแค่ 3 คำหลักก่อน ตู้ (Database) → ลิ้นชัก (Collection) → การ์ด (Document)

ตู้เอกสารคือ Database ในตู้มีลิ้นชักคือ Collection เช่น users และ products ในลิ้นชักมีการ์ดคือ Document แต่ละใบมีช่องไม่เท่ากัน
ตู้ ลิ้นชัก การ์ด คือ Database, Collection และ Document
คำความหมายแบบมือใหม่เทียบฝั่ง SQL
Databaseกลุ่มข้อมูลของแอปหนึ่งตัว (ตู้)Database
Collectionกลุ่มการ์ดเรื่องเดียวกัน เช่น users (ลิ้นชัก)Table
Documentข้อมูลหนึ่งชิ้น (การ์ดหนึ่งใบ)Row (แถว)
Fieldหัวข้อบนการ์ด เช่น name, ageColumn
_idรหัสประจำการ์ด MongoDB ใส่ให้เองถ้าเราไม่ใส่Primary key
JSON / BSONรูปแบบข้อมูล {ชื่อ: ค่า} MongoDB เก็บจริงเป็น BSON-
mongoshโปรแกรมพิมพ์คำสั่งคุยกับ MongoDBpsql, mysql
AtlasMongoDB บนคลาวด์ของบริษัท MongoDB-
Queryคำสั่งค้นหาSELECT

เอกสารของ MongoDB อธิบายว่า document คือหน่วยพื้นฐานของข้อมูลใน MongoDB และเก็บจริงในรูปแบบ BSON ซึ่งเป็น JSON แบบไบนารีที่มีชนิดข้อมูลมากกว่า เช่น วันที่ และตัวเลขหลายแบบ

หน้าตา Document และชนิดข้อมูลที่ใส่ได้

ทุกบรรทัดในการ์ดคือ ช่อง: ค่า ค่าที่ใส่ได้มีหลายแบบ รวมถึงรายการและการ์ดซ้อนในการ์ด

ตัวอย่าง 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 แล้วเปิดโปรแกรมทิ้งไว้ เช็กว่าพร้อม

PowerShell / Terminal
docker --version

โหลดและเปิด MongoDB ด้วยคำสั่งจากหน้า Install MongoDB Community with Docker ของเอกสารทางการ

PowerShell / Terminal
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 ให้รันอยู่เบื้องหลัง

เช็กว่าเปิดแล้ว

PowerShell / Terminal
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 อยู่ข้างใน)

PowerShell / Terminal
docker exec -it mongodb mongosh

วิธีที่ 2 ลง mongosh ในเครื่อง จากหน้าดาวน์โหลด mongosh แล้วปิดเปิดหน้าต่างคำสั่งใหม่ จากนั้นต่อด้วย

PowerShell / Terminal
mongosh --port 27017

ขึ้นบรรทัดรอคำสั่ง test> แปลว่าต่อติดแล้ว พิมพ์คำสั่งในหัวข้อถัดไปต่อที่นี่ได้เลย ออกด้วย exit

เพิ่ม ค้น แก้ ลบข้อมูลใน MongoDB

เลือกตู้ แล้วเพิ่มการ์ดใบแรก

mongosh
use devkub
ผลลัพธ์ที่ควรเห็น
switched to db devkub

ตู้ชื่อ devkub ยังไม่มีก็ไม่เป็นไร MongoDB สร้างให้เองตอนใส่การ์ดใบแรก ลิ้นชักก็เหมือนกัน

mongosh
db.users.insertOne({ name: "เอ", age: 20, phone: "081-xxx" })
ผลลัพธ์ที่ควรเห็น
{
  acknowledged: true,
  insertedId: ObjectId('6ae64be75708d744a9284d0c')
}

เพิ่มทีละหลายใบ ช่องไม่เท่ากันก็ได้

mongosh
db.users.insertMany([
  { name: "บี", age: 25, instagram: "@bee" },
  { name: "ซี", age: 31 }
])
ผลลัพธ์ที่ควรเห็น
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('6ae64be75708d744a9284d0d'),
    '1': ObjectId('6ae64be75708d744a9284d0e')
  }
}

ดูการ์ดทั้งหมดในลิ้นชัก

mongosh
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: "บี" })บี
อายุมากกว่า 21db.users.find({ age: { $gt: 21 } })บี, ซี
อายุน้อยกว่า 21db.users.find({ age: { $lt: 21 } })เอ
มีช่อง instagramdb.users.find({ instagram: { $exists: true } })บี
นับจำนวนdb.users.countDocuments()ได้เลข 3

$gt คือมากกว่า $lt คือน้อยกว่า $gte และ $lte คือมากกว่าหรือเท่ากับ และน้อยกว่าหรือเท่ากับ

แก้การ์ด

mongosh
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 ใบ

ลบการ์ด

mongosh
db.users.deleteOne({ name: "เอ" })
ผลลัพธ์ที่ควรเห็น
{ acknowledged: true, deletedCount: 1 }

ระวัง deleteMany ที่เงื่อนไขว่าง db.users.deleteMany({}) ลบการ์ด ทุกใบ ในลิ้นชัก เพราะเงื่อนไขว่างแปลว่าตรงกับทุกใบ ก่อนลบให้ลองใช้ find กับเงื่อนไขเดียวกันดูก่อนเสมอว่าจะโดนการ์ดใบไหนบ้าง

ซ้อนข้อมูลในการ์ดใบเดียว และกับดัก age กับ Age

ซ้อนข้อมูล

คนหนึ่งมีหลายที่อยู่ ใส่เป็นรายการของการ์ดซ้อนไว้ในใบเดียวได้เลย

mongosh
db.users.insertOne({
  name: "ดี",
  addresses: [
    { type: "บ้าน", city: "เชียงใหม่" },
    { type: "ที่ทำงาน", city: "กรุงเทพ" }
  ]
})

ค้นลงไปในการ์ดซ้อนด้วยจุด .

mongosh
db.users.find({ "addresses.city": "เชียงใหม่" })

ได้การ์ดของดีกลับมา ถ้าเป็นตาราง SQL ต้อง JOIN สองตารางถึงจะได้ผลแบบนี้

กับดัก: age กับ Age

ลองใส่การ์ดที่พิมพ์ชื่อช่องเป็นตัวพิมพ์ใหญ่ แล้วค้นอายุตามปกติ

mongosh
db.users.insertOne({ name: "อี", Age: 28 })
db.users.find({ age: { $gt: 21 } })

ผลลัพธ์ไม่มีการ์ดของอีเลย ทั้งที่อายุ 28 เพราะ MongoDB ถือว่า age กับ Age เป็นคนละช่อง และไม่เตือนอะไรตอนใส่

การ์ดของบีมีช่อง age 25 ส่วนการ์ดของอีพิมพ์เป็น Age 28 พอค้น age มากกว่า 21 จึงเจอแค่บี ไม่เจออี
ชื่อช่องตัวพิมพ์ใหญ่เล็กต่างกัน คือคนละช่อง

ความยืดหยุ่นของ 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 แล้วหยุดและลบกล่อง

PowerShell / Terminal
docker stop mongodb
docker rm mongodb

stop คือปิดกล่อง ส่วน 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 ได้เลยครับ

Quiz ท้ายบท

5 ข้อ · ข้อละ 10 XP

ทดสอบความเข้าใจเรื่อง MongoDB ตอบถูกข้อละ 10 XP

  • 5 ข้อ
  • ไม่จับเวลา
  • เฉลยทันทีทุกข้อ