1. MongoDB 기초 개념

NoSQL vs SQL

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")
}


2. Mongoose 연결 설정

데이터베이스 연결

// 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);


3. 스키마 설계

기본 스키마 정의

// 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,
  },
});