MongoDB는 문서 지향(Document-Oriented) NoSQL 데이터베이스입니다.
| SQL (관계형 DB) | MongoDB |
|---|---|
| Database | Database |
| Table | Collection |
| Row | Document |
| Column | Field |
| Join | Embedded Document / Reference |
| Primary Key | _id |
// SQL의 Row
{
id: 1,
name: "김철수",
email: "[email protected]"
}
// MongoDB의 Document (유연한 구조)
{
_id: ObjectId("507f1f77bcf86cd799439011"),
name: "김철수",
email: "[email protected]",
profile: {
age: 30,
interests: ["coding", "reading"]
},
createdAt: ISODate("2024-01-01T00:00:00Z")
}
// config/database.js - 프로젝트의 실제 구현
import mongoose from "mongoose";
export const connectDatabase = async () => {
try {
await mongoose.connect(process.env.MONGODB_URI, {
dbName: process.env.MONGODB_DB_NAME,
});
console.log("✅ MongoDB 연결됨");
} catch (err) {
console.error("❌ MongoDB 연결 실패:", err);
process.exit(1);
}
};
// 연결 이벤트 리스너
mongoose.connection.on("connected", () => {
console.log("🔗 Mongoose가 MongoDB에 연결되었습니다");
});
mongoose.connection.on("error", (err) => {
console.error("❌ Mongoose 연결 오류:", err);
});
mongoose.connection.on("disconnected", () => {
console.log("🔌 Mongoose 연결이 끊어졌습니다");
});
// 프로세스 종료 시 연결 종료
process.on("SIGINT", async () => {
await mongoose.connection.close();
console.log("MongoDB 연결이 안전하게 종료되었습니다");
process.exit(0);
});
const connectionOptions = {
// 연결 문자열 옵션
useNewUrlParser: true, // 새로운 URL 파서 사용 (deprecated)
useUnifiedTopology: true, // 새로운 서버 검색 엔진 (deprecated)
// 연결 풀 설정
maxPoolSize: 10, // 최대 연결 수
minPoolSize: 5, // 최소 연결 수
maxIdleTimeMS: 10000, // 유휴 연결 최대 시간
// 타임아웃 설정
serverSelectionTimeoutMS: 5000, // 서버 선택 타임아웃
socketTimeoutMS: 45000, // 소켓 타임아웃
// 기타 옵션
family: 4, // IPv4 사용
authSource: "admin", // 인증 DB
};
await mongoose.connect(process.env.MONGODB_URI, connectionOptions);
// models/Conversation.js - 프로젝트의 실제 구현
import mongoose from "mongoose";
// 메시지 서브 스키마
const messageSchema = new mongoose.Schema({
role: {
type: String,
enum: ["user", "assistant", "system"],
required: true,
},
content: {
type: String,
required: true,
},
timestamp: {
type: Date,
default: Date.now,
},
});
// 대화 스키마
const conversationSchema = new mongoose.Schema({
sessionId: {
type: String,
required: true,
unique: true,
index: true,
},
messages: [messageSchema],
metadata: {
ipAddress: String,
userAgent: String,
createdAt: {
type: Date,
default: Date.now,
},
lastAccessIP: String,
lastAccessUserAgent: String,
lastAccessTime: {
type: Date,
default: Date.now,
},
recommendedPlans: [String],
sessionType: {
type: String,
default: "ip_based",
enum: ["ip_based", "user_generated", "anonymous"],
},
totalInteractions: {
type: Number,
default: 0,
},
averageResponseTime: Number,
},
createdAt: {
type: Date,
default: Date.now,
},
updatedAt: {
type: Date,
default: Date.now,
},
});