MongoDB / Mongoose schema ба model

Mongoose schema ба model

Mongoose Schema нь зөвхөн талбарын төрөл тодорхойлоод зогсохгүй — validation, анхдагч утга, виртуал талбар зэрэг өргөн боломжтой. Энэ хичээлд Schema-г нарийвчлан судална.

Schema type-ууд

javascript
const { Schema } = require("mongoose");

const postSchema = new Schema({
  title: String, // товч хэлбэр
  content: { type: String }, // дэлгэрэнгүй хэлбэр
  viewCount: { type: Number },
  published: { type: Boolean },
  createdAt: { type: Date },
  authorId: { type: Schema.Types.ObjectId, ref: "User" }, // ObjectId — ref заана
  tags: { type: [String] }, // String массив
  meta: {
    // Nested object
    likes: Number,
    shares: Number,
  },
});

Нийтлэг Schema type-ууд:

| Type | Тайлбар | | ----------------------- | ----------------------------------------------- | | String | Текст | | Number | Тоо (int болон float хоёуланг) | | Boolean | true / false | | Date | Огноо | | Schema.Types.ObjectId | MongoDB ObjectId — ихэвчлэн ref-тэй хэрэглэнэ | | [String] буюу Array | Массив | | Schema.Types.Mixed | Дурын төрөл (хэрэглэхийг зайлсхий) |

required — заавал байх

javascript
const userSchema = new Schema({
  username: {
    type: String,
    required: true, // анхдагч алдааны мессежтэй
  },
  email: {
    type: String,
    required: [true, "И-мэйл заавал шаардлагатай"], // өөрийн мессежтэй
  },
});

default — анхдагч утга

javascript
const postSchema = new Schema({
  published: {
    type: Boolean,
    default: false,
  },
  viewCount: {
    type: Number,
    default: 0,
  },
  createdAt: {
    type: Date,
    default: Date.now, // функц өгч болно — дуудагдах үед утга тооцогдоно
  },
  role: {
    type: String,
    default: "user",
  },
});

unique — давхардахгүй

javascript
const userSchema = new Schema({
  email: {
    type: String,
    unique: true, // MongoDB-д unique index үүснэ
  },
});

unique нь Mongoose-ийн validation биш — MongoDB-д index үүсгэдэг. Давхардсан утга оруулахад MongoDB-ийн алдаа гарна.

validate — өөрийн validation

javascript
const userSchema = new Schema({
  age: {
    type: Number,
    validate: {
      validator: (v) => v >= 0 && v <= 120,
      message: (props) => `${props.value} буруу нас — 0–120 байх ёстой`,
    },
  },
  phone: {
    type: String,
    validate: {
      validator: (v) => /^\d{8}$/.test(v),
      message: "Утасны дугаар 8 оронтой тоо байх ёстой",
    },
  },
});

timestamps — автомат огноо

timestamps: true тохируулбал createdAt ба updatedAt талбарыг Mongoose автоматаар нэмж, удирддаг:

javascript
const postSchema = new Schema(
  {
    title: String,
    content: String,
  },
  {
    timestamps: true, // createdAt, updatedAt автоматаар нэмэгдэнэ
  },
);

Гараар createdAt тодорхойлох шаардлагагүй болно.

Virtual field — тооцоолсон талбар

Virtual field нь database-д хадгалагддаггүй — уншихад тооцоогдон гардаг. Нэрийг хоёр хэсгээс нийлүүлэх зэрэг энгийн хувиргалтад тохиромжтой:

javascript
const userSchema = new Schema({
  firstName: String,
  lastName: String,
  xp: { type: Number, default: 0 },
});

// Virtual: бүтэн нэр
userSchema.virtual("fullName").get(function () {
  return `${this.firstName} ${this.lastName}`;
});

// Virtual: дүн шатлал
userSchema.virtual("level").get(function () {
  return Math.floor(this.xp / 100) + 1;
});

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

const user = await User.findOne({ firstName: "Болд" });
console.log(user.fullName); // "Болд Батаа"
console.log(user.level); // 4  (xp: 350 → floor(350/100)+1)

Virtual field нь toJSON() болон toObject()-д анхдагчаар ороходгүй:

javascript
// Virtual-уудыг JSON-д оруулах
const userSchema = new Schema({ ... }, {
  toJSON:   { virtuals: true },
  toObject: { virtuals: true }
})

Schema-г тусдаа файлд байрлуулах

код
models/
├── User.ts
├── Post.ts
└── Comment.ts
typescript
// models/User.ts
import mongoose, { Schema, Document } from "mongoose";

export interface IUser extends Document {
  username: string;
  email: string;
  xp: number;
  role: "user" | "admin";
  createdAt: Date;
  updatedAt: Date;
  level: number; // virtual
}

const userSchema = new Schema<IUser>(
  {
    username: { type: String, required: true, unique: true, trim: true },
    email: { type: String, required: true, unique: true, lowercase: true },
    xp: { type: Number, default: 0 },
    role: { type: String, enum: ["user", "admin"], default: "user" },
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
  },
);

userSchema.virtual("level").get(function () {
  return Math.floor(this.xp / 100) + 1;
});

export default mongoose.model<IUser>("User", userSchema);

Дараагийн хичээлд:

Mongoose-ийн find, create, update, delete методууд болон populate-ийг ашиглан CRUD бичнэ.