공식 Node.js 드라이버로 연결하기
학습자는 MongoClient를 만들고 연결 풀을 관리하며 네이티브 드라이버를 사용해 Node.js 애플리케이션에서 CRUD 작업을 실행합니다.
공식 Node.js 드라이버로 연결하기은(는) CoddyKit의 무료 MongoDB Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 MongoDB Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
공식 MongoDB Node.js 드라이버
MongoDB Node.js 드라이버(mongodb npm 패키지)는 Node.js 애플리케이션에서 MongoDB에 연결하기 위한 공식 저수준 라이브러리입니다. 추상화 계층 없이 모든 MongoDB 기능에 직접 접근할 수 있으므로, 성능이 중요한 코드, 마이크로서비스 및 스크립트에 적합합니다. 이 드라이버는 MongoDB, Inc.에서 유지 관리하며 새로운 MongoDB 서버 기능을 빠르게 반영합니다.
// 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';MongoClient 생성
MongoClient 클래스는 모든 상호 작용의 시작점입니다. 연결 문자열(URI)과 선택적인 옵션 객체를 사용하여 인스턴스를 생성합니다. 연결 문자열에는 호스트, 포트, 자격 증명 및 연결 매개변수가 인코딩됩니다. MongoDB Atlas를 사용하는 경우 Atlas UI에서 연결 문자열을 복사한 다음 자리 표시자 비밀번호를 바꾸십시오. 애플리케이션마다 MongoClient를 하나만 생성하고 재사용하십시오. 요청마다 새로 생성해서는 안 됩니다.
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()MongoDB에 연결하기
연결 풀을 설정하려면 client.connect()를 호출하십시오. 드라이버는 서버에 대한 연결 풀을 유지하며, 일반적으로 5~100개의 연결을 운영 간에 재사용합니다. 애플리케이션이 시작될 때 connect()를 한 번만 호출하면 됩니다. 명시적으로 connect()를 호출하지 않고도 운영을 직접 실행할 수 있습니다. 이 경우 드라이버가 첫 번째 운영에서 지연 방식으로 연결합니다. 애플리케이션을 종료할 때 client.close()를 호출하십시오.
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);웹 서버의 싱글턴 패턴
웹 서버(Express, Fastify, NestJS)에서는 MongoClient를 시작 시 한 번 생성하고 모든 요청 처리기가 공유하는 모듈 수준 싱글턴으로 만들어야 합니다. 요청마다 새 MongoClient를 생성하면 사용 가능한 연결이 고갈되고 성능이 크게 저하됩니다. 일반적인 패턴은 서버 시작 함수에서 연결한 다음 client 또는 db 참조를 내보내는 것입니다.
// 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;컬렉션 참조 가져오기
db.collection('collectionName')을 호출하여 컬렉션에 접근하십시오. 이 호출은 네트워크 요청 없이 Collection 객체를 반환하며, 단순한 참조일 뿐입니다. 시작 시 컬렉션 참조를 가져와 모듈 수준 변수로 저장하거나, 각 함수 안에서 필요할 때 직접 가져올 수 있습니다. 컬렉션 참조는 가볍고 요청 간에 안전하게 재사용할 수 있습니다.
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 운영: 삽입
insertOne() 또는 insertMany()를 사용하여 문서를 삽입하십시오. 드라이버는 제공되지 않은 경우 _id를 자동으로 생성하고 삽입된 ID를 반환합니다. 결과 객체의 insertedId(insertOne의 경우) 또는 insertedIds 맵(insertMany의 경우)을 사용하면 생성된 항목을 추적할 수 있습니다. 두 운영 모두 writeConcern을 지정할 수 있는 options 객체를 받습니다.
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 운영: 읽기
단일 문서를 가져오려면 findOne(filter)을 사용하고, 일치하는 모든 문서를 순회하는 커서를 가져오려면 find(filter)를 사용하십시오. 결과가 적을 때는 .toArray()로 커서를 배열로 변환하고, 결과가 많을 때는 for await...of로 순회하십시오. 두 메서드 모두 projection, sort, skip, limit 및 기타 쿼리 수정자를 위한 두 번째 옵션 인수를 받습니다.
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 운영: 업데이트
updateOne(), updateMany() 또는 findOneAndUpdate()를 사용하여 문서를 업데이트하십시오. 필터는 업데이트할 문서를 선택하고, 업데이트 문서는 $set, $inc, $push와 같은 연산자를 사용하여 변경 사항을 지정합니다. updateOne()과 updateMany()는 matchedCount와 modifiedCount가 포함된 결과를 반환합니다. 문서가 없을 때 해당 문서를 생성하려면 upsert: true를 사용하십시오.
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 운영: 삭제
deleteOne() 또는 deleteMany()를 사용하여 문서를 삭제하십시오. 필터가 제거할 문서를 결정합니다. 결과에는 deletedCount가 포함됩니다. 운영 환경에서는 안전을 위해 deleteMany를 실행하기 전에 항상 먼저 find로 필터를 확인하십시오. 실수로 컬렉션의 모든 문서를 삭제하는 것은 흔하면서도 치명적인 실수입니다. 감사 추적이 필요하다면 실제로 삭제하는 대신 deletedAt 필드를 설정하는 소프트 삭제를 고려하십시오.
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 } });
}집계 파이프라인 실행
collection.aggregate(pipeline)을 사용하여 집계 파이프라인을 실행하십시오. 이 메서드는 배열로 변환하거나 순회할 수 있는 커서를 반환합니다. 파이프라인 단계는 객체 배열로 전달합니다. 드라이버는 파이프라인을 MongoDB의 집계 엔진으로 보내고 결과를 스트리밍 방식으로 돌려받습니다. 결과가 매우 많을 때는 모든 결과를 한 번에 메모리에 로드하지 않도록 .toArray()를 호출하는 대신 커서를 직접 순회하십시오.
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);
}연결 풀 구성
MongoClient는 서버 연결을 자동으로 관리하는 연결 풀을 유지합니다. 주요 옵션은 다음과 같습니다. maxPoolSize(최대 연결 수, 호스트당 기본값 5), minPoolSize(유지할 최소 연결 수), connectTimeoutMS, socketTimeoutMS입니다. 트래픽이 많은 API에서는 maxPoolSize를 늘리되, 연결마다 발생하는 MongoDB의 메모리 오버헤드와 균형을 맞추십시오. Atlas 지표를 사용하여 풀 사용률을 모니터링하십시오.
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
});빠른 확인
이 단원에서 배운 MongoDB 및 NoSQL 데이터베이스 개념을 이해했는지 확인하십시오.
단원 요약
이 단원에서는 다음을 배웠습니다. 시작 시 MongoClient를 하나 생성하고 싱글턴으로 재사용하십시오. 요청마다 생성해서는 안 됩니다. client.db()와 db.collection()으로 데이터베이스 및 컬렉션 참조를 가져오십시오. 이러한 참조는 가벼운 객체 참조입니다. 또한 CRUD 운영에는 insertOne/insertMany, findOne/find, updateOne/updateMany/findOneAndUpdate, deleteOne/deleteMany를 사용하십시오. 다음에는 네이티브 드라이버보다 높은 수준의 추상화인 Mongoose 스키마, 모델 및 가상 필드를 살펴보겠습니다.
AI 튜터와 함께 JavaScript을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 30
- 레슨
- 120
자주 묻는 질문
“공식 Node.js 드라이버로 연결하기” 강의는 무료인가요?
네 — “공식 Node.js 드라이버로 연결하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 MongoDB Academy 강의 전체를 잠금 해제할 수 있습니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“공식 Node.js 드라이버로 연결하기”에서 뭘 배우나요?
학습자는 MongoClient를 만들고 연결 풀을 관리하며 네이티브 드라이버를 사용해 Node.js 애플리케이션에서 CRUD 작업을 실행합니다. 브라우저에서 직접 실행하는 실습 코드로 MongoDB Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
MongoDB Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 MongoDB Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“공식 Node.js 드라이버로 연결하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 MongoDB Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 MongoDB Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 공식 Node.js 드라이버로 연결하기
- Mongoose 스키마, 모델 및 가상 속성
- Mongoose 쿼리, 연결 및 Lean 문서
- Mongoose 미들웨어: 사전 및 사후 훅