การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ
ผู้เรียนจะสร้าง MongoClient จัดการกลุ่มการเชื่อมต่อ และดำเนินการ CRUD จากแอปพลิเคชัน Node.js ด้วยไดรเวอร์แบบเนทีฟ
การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ เป็นบทเรียน MongoDB Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน MongoDB Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส MongoDB Academy มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
The Official MongoDB Node.js Driver
The MongoDB Node.js driver (mongodb npm package) is the official, low-level library for connecting to MongoDB from Node.js applications. It provides direct access to all MongoDB features without an abstraction layer, making it ideal for performance-critical code, microservices, and scripts. The driver is maintained by MongoDB, Inc. and closely tracks new MongoDB server features.
// Install the driver
// npm install mongodb
// Or with yarn:
// yarn add mongodb
// The driver exports MongoClient as its main entry point
const { MongoClient, ObjectId, ServerApiVersion } = require('mongodb');
// or ES module:
// import { MongoClient, ObjectId } from 'mongodb';Creating a MongoClient
The MongoClient class is the entry point for all interactions. Instantiate it with your connection string (URI) and an optional options object. The connection string encodes the host, port, credentials, and connection parameters. For MongoDB Atlas, copy the connection string from the Atlas UI and replace the placeholder password. Create one MongoClient per application and reuse it—do not create a new one per request.
const { MongoClient, ServerApiVersion } = require('mongodb');
const uri = process.env.MONGODB_URI;
// URI format: mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true
const client = new MongoClient(uri, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true
}
});
// client is not yet connected — connecting happens lazily or via connect()Connecting to MongoDB
Call client.connect() to establish a connection pool. The driver maintains a connection pool—typically 5-100 connections to the server—and reuses them across operations. You only need to call connect() once at application startup. Operations can also be called directly without explicit connect()—the driver connects lazily on the first operation. Call client.close() on application shutdown.
async function main() {
try {
await client.connect();
console.log('Connected to MongoDB');
// Get database reference
const db = client.db('myDatabase');
// Ping the server to verify connection
await db.command({ ping: 1 });
console.log('Ping successful');
// Run your application logic here...
} finally {
// Always close when done
await client.close();
}
}
main().catch(console.error);Singleton Pattern for Web Servers
In a web server (Express, Fastify, NestJS), the MongoClient must be a module-level singleton that is created once on startup and shared by all request handlers. Creating a new MongoClient per request would exhaust available connections and severely degrade performance. The standard pattern is to connect in the server startup function and export the client or db reference.
// db.js — module-level singleton
const { MongoClient } = require('mongodb');
let client;
let db;
async function connectToDatabase() {
if (db) return db; // return existing connection
client = new MongoClient(process.env.MONGODB_URI);
await client.connect();
db = client.db(process.env.DB_NAME || 'myapp');
return db;
}
module.exports = { connectToDatabase };
// In your Express app:
// const { connectToDatabase } = require('./db');
// const db = await connectToDatabase();
// app.locals.db = db;Getting Collection References
Access a collection by calling db.collection('collectionName'). This returns a Collection object without any network call—it is just a reference. You can get collection references at startup and store them as module-level variables, or get them inline within each function. Collection references are lightweight and safe to reuse across requests.
const db = client.db('ecommerce');
// Get collection references
const usersCollection = db.collection('users');
const ordersCollection = db.collection('orders');
const productsCollection = db.collection('products');
// TypeScript: provide a document type for type safety
// const users = db.collection<UserDocument>('users');
// Collections can also be retrieved inline:
async function getUser(id) {
return client.db('ecommerce').collection('users').findOne({ _id: id });
}CRUD Operations: Insert
Insert documents using insertOne() or insertMany(). The driver automatically generates an _id if not provided and returns the inserted IDs. The result object's insertedId (for insertOne) or insertedIds map (for insertMany) let you track what was created. Both operations accept an options object where you can specify writeConcern.
const db = client.db('shop');
const products = db.collection('products');
// Insert one document
const insertResult = await products.insertOne({
name: 'Mechanical Keyboard',
price: 149.99,
category: 'Electronics',
stock: 50
});
console.log('Inserted ID:', insertResult.insertedId);
// Insert multiple documents
const bulkResult = await products.insertMany([
{ name: 'Mouse Pad', price: 19.99, category: 'Accessories' },
{ name: 'USB Hub', price: 39.99, category: 'Electronics' }
]);
console.log('Inserted count:', bulkResult.insertedCount);CRUD Operations: Read
Use findOne(filter) to retrieve a single document or find(filter) to get a cursor over all matching documents. Convert a cursor to an array with .toArray() for small result sets, or iterate with for await...of for large ones. Both methods accept a second options argument for projection, sort, skip, limit, and other query modifiers.
const users = db.collection('users');
// Find a single user by email
const user = await users.findOne(
{ email: 'alice@example.com' },
{ projection: { password: 0 } } // exclude sensitive fields
);
// Find multiple documents with options
const activeUsers = await users.find(
{ active: true, role: 'admin' },
{
projection: { name: 1, email: 1 },
sort: { createdAt: -1 },
limit: 50
}
).toArray();
// Iterate large results without loading all into memory
const cursor = users.find({ active: true });
for await (const user of cursor) {
await processUser(user);
}CRUD Operations: Update
Update documents with updateOne(), updateMany(), or findOneAndUpdate(). The filter selects which documents to update and the update document specifies the changes using operators like $set, $inc, and $push. updateOne() and updateMany() return a result with matchedCount and modifiedCount. Use upsert: true to create the document if it does not exist.
const orders = db.collection('orders');
// Update one order's status
const updateResult = await orders.updateOne(
{ _id: orderId },
{ $set: { status: 'shipped', shippedAt: new Date() } }
);
console.log('Modified:', updateResult.modifiedCount);
// Atomic: find, update, and return the updated document
const updatedOrder = await orders.findOneAndUpdate(
{ _id: orderId },
{ $set: { status: 'delivered' }, $push: { statusHistory: { status: 'delivered', at: new Date() } } },
{ returnDocument: 'after' } // return the document AFTER update
);CRUD Operations: Delete
Delete documents using deleteOne() or deleteMany(). The filter determines which documents to remove. The result contains deletedCount. For safety in production, always test your filter with a find first before running deleteMany—accidentally deleting all documents in a collection is a common and catastrophic mistake. Consider soft deletes (setting a deletedAt field) instead of physical deletion for audit trails.
const sessions = db.collection('sessions');
// Delete one session
const deleteResult = await sessions.deleteOne({ _id: sessionId });
console.log('Deleted:', deleteResult.deletedCount);
// Delete all expired sessions — test filter first!
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
// 1. Test: how many would be deleted?
const count = await sessions.countDocuments({ expiresAt: { $lt: thirtyDaysAgo } });
console.log('Would delete:', count);
// 2. Only delete after confirming the count looks right
if (count < 10000) { // sanity check
await sessions.deleteMany({ expiresAt: { $lt: thirtyDaysAgo } });
}Running Aggregation Pipelines
Execute aggregation pipelines using collection.aggregate(pipeline). This returns a cursor that you convert to an array or iterate. Pipeline stages are passed as an array of objects. The driver sends the pipeline to MongoDB's aggregation engine and streams back results. For very large result sets, iterate the cursor directly rather than calling .toArray() to avoid loading everything into memory at once.
const orders = db.collection('orders');
// Revenue report by category
const report = await orders.aggregate([
{ $match: { status: 'completed', createdAt: { $gte: new Date('2024-01-01') } } },
{ $group: { _id: '$category', total: { $sum: '$amount' }, count: { $sum: 1 } } },
{ $sort: { total: -1 } }
]).toArray();
console.log('Revenue report:', report);
// For large aggregations, iterate the cursor:
const cursor = orders.aggregate([...largeComplexPipeline]);
for await (const doc of cursor) {
await writeToReport(doc);
}Connection Pool Configuration
The MongoClient maintains a connection pool that automatically manages connections to the server. Key options: maxPoolSize (maximum connections, default 5 per host), minPoolSize (keep-alive minimum), connectTimeoutMS, and socketTimeoutMS. For high-traffic APIs, increase maxPoolSize but balance it against MongoDB's per-connection memory overhead. Monitor pool utilization using Atlas metrics.
const client = new MongoClient(uri, {
maxPoolSize: 20, // max 20 connections to the server
minPoolSize: 5, // keep at least 5 connections warm
connectTimeoutMS: 5000, // fail fast if can't connect in 5s
socketTimeoutMS: 45000, // idle socket timeout
serverSelectionTimeoutMS: 5000 // how long to wait to find an available server
});Quick Check
Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.
Lesson Recap
In this lesson you learned: create one MongoClient at startup and reuse it as a singleton — never create one per request, get database and collection references with client.db() and db.collection() — these are lightweight object references, and use insertOne/insertMany, findOne/find, updateOne/updateMany/findOneAndUpdate, and deleteOne/deleteMany for CRUD operations. Next up we explore Mongoose schemas, models, and virtuals as a higher-level abstraction over the native driver.
คำถามที่พบบ่อย
บทเรียน “การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส MongoDB Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส MongoDB Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ”
ผู้เรียนจะสร้าง MongoClient จัดการกลุ่มการเชื่อมต่อ และดำเนินการ CRUD จากแอปพลิเคชัน Node.js ด้วยไดรเวอร์แบบเนทีฟ คุณปฏิบัติ MongoDB Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน MongoDB Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน MongoDB Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน MongoDB Academy นี้ได้ไหม
ได้ บทเรียน MongoDB Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การเชื่อมต่อด้วยไดรเวอร์ Node.js อย่างเป็นทางการ
- สคีมา โมเดล และพร็อพเพอร์ตีเสมือนของ Mongoose
- การค้นหา การเชื่อมต่อคำสั่ง และเอกสารแบบ Lean ของ Mongoose
- มิดเดิลแวร์ของ Mongoose: ฮุกก่อนและหลัง