본문 바로가기
기타 지식 및 애로사항

MongoDB - Mongoose 이용하여 채팅 및 알림 관련 스키마 정의하기

by prometedor 2023. 10. 3.

MongoDB

Mongoose

ㄴ MongoDB와 함께 사용되는 Node.js 기반의 ODM(Object Data Modeling) 라이브러리 임
ㄴ 데이터베이스 스키마를 정의하고 데이터를 다루는 데 도움을 줌

 

Mongoose 스키마(Schema) 정의하기

chat.js

import mongoose from "mongoose";

const { Schema } = mongoose;
const { Types: { ObjectId } } = Schema;
const chatSchema = new Schema({
  room: { // 채팅방 아이디
    type: ObjectId,
    required: true,
    ref: 'Room',
  },
  user: { // 채팅을 한 사람
    type: ObjectId,
    required: true,
    ref: 'User',
  },
  chat: String, // 채팅 내역
  photo: String, // 이미지 주소(gif 랑 jpg 등 모두 받을 수 있게 하고 싶음?)
  createdAt: { // 채팅 시간
    type: Date,
    default: Date.now,
  },
});

const Chat = mongoose.model("Chat", chatSchema);
export default Chat;

 

ㄴ chatSchema는 채팅 데이터의 구조를 명시함

ㄴ 이 스키마에 따라 MongoDB에 저장된 채팅 데이터의 형태가 결정됨

ㄴ 각 필드(필드는 컬렉션 내에서 데이터를 저장하는 데 사용되는 항목)의 역할
     ㄴ room : 채팅방의 아이디를 저장하는 필드

         ㄴ 이 필드의 타입은 ObjectId로 설정되어 있으며, ref 속성을 통해 'Room'이라는 컬렉션과 연결됨

         ㄴ 이는 채팅 데이터와 채팅방 데이터 간의 관계를 나타냄
     ㄴ user : 채팅을 한 사용자의 이름을 저장하는 필드

         ㄴ 이 필드의 타입은 문자열(String)이며, 필수 필드(required: true)로 설정되어 있어 사용자 이름이 반드시 제공되어야 함
     ㄴ chat : 실제 채팅 내용을 저장하는 필드

          ㄴ 이 필드의 타입은 문자열(String)
     ㄴ photo : 채팅에 첨부된 이미지의 주소를 저장하는 필드

          ㄴ 이 필드의 타입은 문자열(String)
     ㄴ createdAt : 채팅이 생성된 시간을 저장하는 필드

          ㄴ 이 필드의 타입은 날짜와 시간(Date)으로 설정되어 있으며, 기본값(default)으로 현재 시간을 사용하도록 설정됨
ㄴ 스키마를 정의한 후에는 exports를 통해 이 스키마를 외부에서 사용할 수 있도록 내보냄

ㄴ 이렇게 정의된 스키마를 기반으로 실제 채팅 데이터를 MongoDB에 저장하고 조회할 수 있게 됨

 

 

room.js

import mongoose from "mongoose"; // Mongoose 모듈을 가져옴

const { Schema } = mongoose; // Mongoose에서 스키마를 정의하기 위해 Schema 객체를 가져옴
			     // ㄴ 스키마는 MongoDB 컬렉션의 구조를 정의하는 역할을 함
const roomSchema = new Schema({ // MongoDB의 room 컬렉션을 위한 스키마를 생성
				// roomSchema는 MongoDB 컬렉션의 각 문서(document)가 
                                // 가질 필드와 데이터 유형을 정의
  title: { // 방 제목
    type: String,
    required: true,
  },
  createdAt: { // 생성 시간
    type: Date,
    default: Date.now,
  },
});

const Room = mongoose.model("Room", roomSchema); // 스키마를 기반으로 MongoDB 모델을 생성
					 	// Room 모델은 room 컬렉션과 상호작용하기 위한 인터페이스를 제공
export default Room; // Room 모델을 내보냄
		     // 이렇게 내보낸 모델을 다른 파일에서 가져와 MongoDB 컬렉션과 상호작용할 수 있음

ㄴ title : 방의 제목을 나타내는 필드

    ㄴ 데이터 유형은 문자열(String)이며, required: true로 설정되어 필수 필드임을 나타냄
ㄴ createdAt : 방이 생성된 시간을 나타내는 필드

    ㄴ 데이터 유형은 날짜(Date)이며, default 옵션을 통해 기본값을 현재 날짜로 설정

 

 

user.js

import mongoose from "mongoose";

const { Schema } = mongoose;
const { Types: { ObjectId } } = Schema;
const userSchema = new Schema ({
  mno: { // 사용자 고유 번호
    type: Number,
    required: true,
  },
  nick: { // 사용자 닉네임
    type: String,
    required: true,
  },
  rooms: [{
    type: ObjectId,
    ref: 'Room',
  }],

});

const User = mongoose.model("User", userSchema);
export default User;

ㄴ mno : 사용자의 고유 번호를 나타내는 필드

    ㄴ 이 필드의 데이터 타입은 숫자(Number)로 정의되어 있으며, required: true로 설정되어 있어서 필수 입력 필드임

    ㄴ 사용자의 고유 번호를 저장하는 용도로 사용
ㄴ nick : 사용자의 닉네임을 나타내는 필드

    ㄴ 이 필드의 데이터 타입은 문자열(String)로 정의되어 있으며, 역시 required: true로 설정되어 있어서 필수 입력 필드임

    ㄴ 사용자의 닉네임을 저장하는 용도로 사용

 

 

noti.js

import mongoose from "mongoose";

const { Schema } = mongoose;
const notiSchema = new Schema ({
  nlno: {
    type: Number,
    required: true,
  },
  mno: {
    type: Number,
    required: true,
  },
  ntno: {
    type: Number,
    required: true,
  },
  content: {
    type: String,
    required: true,
  },
  url: {
    type: String,
    required: true,
  },
  noti_state: {
    type: Number,
    required: true,
    default: 0,
  },
});

const Noti = mongoose.model("Noti", notiSchema);
export default Noti;

ㄴ nlno : 알림 기록 번호를 나타내는 필드

    ㄴ 데이터 유형은 숫자(Number)이며, required: true로 설정되어 필수 필드임을 나타냄
ㄴ mno : 회원 번호를 나타내는 필드

    ㄴ 데이터 유형은 숫자(Number)이며, required: true로 설정되어 필수 필드임을 나타냄
ㄴ ntno : 알림 유형 번호를 나타내는 필드

    ㄴ 데이터 유형은 숫자(Number)이며, required: true로 설정되어 필수 필드임을 나타냄
ㄴ content : 알림 내용을 나타내는 필드

    ㄴ 데이터 유형은 문자열(String)이며, required: true로 설정되어 필수 필드임을 나타냄
ㄴ url : 알림과 연결된 링크를 나타내는 필드

    ㄴ 데이터 유형은 문자열(String)이며, required: true로 설정되어 필수 필드임을 나타냄
ㄴ noti_state : 알림 확인 상태를 나타내는 필드

    ㄴ 데이터 유형은 숫자(Number)이며, 기본값으로 0을 가지고 있음

 

 

index.js

import mongoose from "mongoose";

const mongodbConnect = () => {
  const { NODE_ENV, MONGO_URI, MONGODB_USER, MONGODB_PASS } = process.env;

  console.log("MONGODB연결 시작");
  const MONGO_URL = `mongodb://${MONGODB_USER}:${MONGODB_PASS}@${MONGO_URI}?directConnection=true`;
  if (NODE_ENV !== "production") {
    mongoose.set("debug", true);
  }
  mongoose
    .connect(MONGO_URL, {
      dbName: "sns-tp",
      useNewUrlParser: true,
    })
    .then(() => {
      console.log("MongoDB 연결성공");
    })
    .catch((err) => {
      console.error("@mongoDB 연결 에러발생@", err);
    });
};

import Chat from "./chat";
import Room from "./room";
import User from "./user";
import Noti from "./noti";

mongoose.connection.on("error", (error) => {
  console.error("몽고디비 연결 에러", error);
});
mongoose.connection.on("disconnected", () => {
  console.error("몽고디비 연결이 끊겼습니다. 연결을 재시도합니다.");
  mongodbConnect();
});

export default mongodbConnect;

ㄴ MONGO_URL 에 설정된 MONGODB_USER, MONGODB_PASS, MONGO_URI 값은 .env 파일에 설정해둠

ㄴ import Chat from "./chat" 이런식으로 import 문을 추가하여 index.js 가 실행될 때 테이블 생성하도록 함