🍃
Веб-сайт

MongoDB ва Mongoose: Node.js'да NoSQL маълумотлар базаси билан ишлаш

29.03.2025
← Барча мақолалар

Замонавий веб-иловаларни яратаётган ҳар бир backend дастурчи эртами-кечми маълумотларни қаерда ва қандай сақлаш масаласига дуч келади. Анъанавий SQL маълумотлар базалари узоқ йиллар давомида саноат стандарти бўлиб келган, бироқ Node.js экотизими кўтарилиши билан MongoDB номли ҳужжатга асосланган NoSQL база айниқса кенг тарқалди. Ушбу мақолада MongoDB нима эканлигини, унинг SQL'дан қандай фарқ қилишини ва Mongoose кутубхонаси ёрдамида Node.js иловаларида у билан қулай ишлашни амалий код мисоллари билан кўриб чиқамиз.

MongoDB нима ва у SQL'дан нимаси билан фарқланади

MongoDB — бу маълумотларни жадваллар ва қаторлар эмас, балки ҳужжатлар кўринишида сақлайдиган NoSQL маълумотлар базаси. Ҳар бир ҳужжат BSON форматида бўлиб, амалда JSON объектига жуда ўхшайди: калит-қиймат жуфтликлари, ички объектлар ва массивларни ўз ичига олиши мумкин. Ҳужжатлар коллекцияларга гуруҳланади, бу эса SQL'даги жадвалга ўхшаш тушунча, бироқ муҳим фарқ шундаки, битта коллекциядаги ҳужжатлар бир хил тузилишга эга бўлиши шарт эмас.

SQL базаларида сиз аввал қатъий схема аниқлайсиз: қайси устунлар бор, уларнинг турлари қандай ва қайси чекловлар амал қилади. MongoDB эса схемага мослашувчан ёндашади — битта фойдаланувчи ҳужжатида телефон рақами бўлиши, бошқасида эса бўлмаслиги мумкин ва база буни бемалол қабул қилади. Бу мослашувчанлик иловангиз талаблари тез ўзгариб турадиган босқичда жуда қулай, чунки ҳар сафар миграция ёзиш шарт эмас.

Яна бир туб фарқ — боғланишлар билан ишлаш. SQL'да маълумотлар нормаллаштирилади ва JOIN операциялари орқали жадваллар бирлаштирилади. MongoDB'да эса кўпинча боғлиқ маълумотлар битта ҳужжат ичига жойлаштирилади, бу ўқиш тезлигини оширади, чунки битта сўров билан бутун маълумотни олиш мумкин. Албатта, ҳар бир ёндашувнинг ўз афзалликлари ва камчиликлари бор, шу сабабли лойиҳа хусусиятига қараб тўғри танлов қилиш зарур.

Mongoose нима ва нима учун керак

MongoDB'нинг ўзи жуда эркин, яъни ҳеч қандай тузилишни мажбурламайди. Бу кичик лойиҳаларда қулай бўлса-да, катта иловаларда тартибсизликка олиб келиши мумкин. Айнан шу ерда Mongoose ёрдамга келади. Mongoose — бу Node.js учун ODM (Object Data Modeling) кутубхонаси бўлиб, у MongoDB ҳужжатлари устига схема қатламини қўшади ва маълумотлар билан объектлар орқали ишлаш имконини беради.

Mongoose ёрдамида сиз ҳар бир коллекция учун аниқ схема белгилайсиз: қайси майдонлар бор, уларнинг турлари, стандарт қийматлари ва валидация қоидалари. Сўнг шу схема асосида модель яратилади ва айнан шу модель орқали барча CRUD амаллари бажарилади. Бу ёндашув кодингизни тартибли, башоратли ва хавфсизроқ қилади, чунки нотўғри тузилишдаги маълумот базага ёзилмасдан олдин ушлаб қолинади.

Базага уланиш

Ишни бошлаш учун аввал mongoose пакетини ўрнатамиз ва MongoDB серверига уланамиз. Уланиш одатда илова ишга тушишида бир марта амалга оширилади ва кейин Mongoose уланишни ўзи бошқаради.

const mongoose = require('mongoose');

async function connectDB() {
  try {
    await mongoose.connect('mongodb://127.0.0.1:27017/myapp');
    console.log('MongoDB базасига муваффақиятли уланилди');
  } catch (err) {
    console.error('Уланишда хатолик:', err.message);
    process.exit(1);
  }
}

connectDB();

Схема ва моделни аниқлаш

Энди фойдаланувчилар учун схема яратамиз. Схемада ҳар бир майдон тури, мажбурийлиги ва қўшимча қоидалари кўрсатилади. Сўнгра схема асосида модель ҳосил қиламиз — бу модель билан биз келажакда барча амалларни бажарамиз.

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  age: { type: Number, min: 0 },
  isActive: { type: Boolean, default: true },
  createdAt: { type: Date, default: Date.now }
});

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

CRUD амаллар: яратиш, ўқиш, янгилаш, ўчириш

CRUD — бу Create, Read, Update ва Delete сўзларининг қисқартмаси бўлиб, ҳар қандай маълумотлар базаси билан ишлашнинг асосини ташкил этади. Mongoose ушбу амалларни жуда интуитив методлар орқали тақдим этади. Қуйида янги ҳужжат яратиш, уни топиш, янгилаш ва ўчириш мисолларини кўрамиз.

// Яратиш (Create)
const newUser = await User.create({
  name: 'Aziz Karimov',
  email: 'aziz@example.com',
  age: 28
});

// Ўқиш (Read)
const allUsers = await User.find({ isActive: true });
const oneUser = await User.findById(newUser._id);

// Янгилаш (Update)
await User.findByIdAndUpdate(newUser._id, { age: 29 });

// Ўчириш (Delete)
await User.findByIdAndDelete(newUser._id);

Бу методлар Promise қайтаради, шунинг учун улар билан async/await ёки then/catch синтаксисидан фойдаланиш мумкин. find методи шартга мос барча ҳужжатларни массив кўринишида қайтаради, findById эса ID бўйича битта ҳужжатни топади. Бу ёндашув кодни ўқилувчан ва осон тушуниладиган қилади.

Валидация билан маълумотлар яхлитлигини сақлаш

Валидация — бу базага нотўғри ёки тўлиқсиз маълумот тушиб қолишининг олдини олишнинг энг муҳим механизми. Mongoose схема даражасида валидацияни қўллаб-қувватлайди, яъни сиз required, min, max, enum каби қоидаларни тўғридан-тўғри схемада белгилаб қўясиз. Агар маълумот ушбу қоидаларга мос келмаса, save ёки create амали хатолик билан тўхтайди ва база бузилмайди.

const productSchema = new mongoose.Schema({
  title: { type: String, required: true, minlength: 3 },
  price: { type: Number, required: true, min: 0 },
  status: {
    type: String,
    enum: ['active', 'draft', 'archived'],
    default: 'draft'
  }
});

Бундай ёндашув билан сиз бизнес мантиғингизнинг бир қисмини базага энг яқин қатламга жойлаштирасиз, бу эса хатоларни эрта босқичда ушлаб қолишга ёрдам беради. Валидация хатоларини try/catch блоки орқали тутиб олиб, фойдаланувчига тушунарли хабар бериш мумкин.

Populate орқали ҳужжатлар ўртасидаги боғланиш

Гарчи MongoDB ҳужжатга асосланган бўлса-да, баъзан маълумотларни алоҳида коллекцияларга ажратиб, улар ўртасида ҳавола ўрнатиш мантиқан тўғрироқ бўлади. Масалан, ҳар бир буюртма қайси фойдаланувчига тегишли эканлигини сақлаш учун ref орқали боғланиш яратилади. Populate методи эса шу ҳаволани автоматик тўлдириб, боғланган ҳужжатни бутунлигича келтириб беради.

const orderSchema = new mongoose.Schema({
  product: String,
  amount: Number,
  user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});
const Order = mongoose.model('Order', orderSchema);

// Боғланган фойдаланувчи маълумотларини ҳам олиш
const orders = await Order.find().populate('user');

Индекслар ва NoSQL қачон мос келади

Маълумотлар ҳажми ўсгани сайин сўровлар секинлаша бошлайди, айниқса тез-тез изланадиган майдонларда. Буни ҳал қилиш учун индекслардан фойдаланилади — улар базага маълум майдон бўйича тез қидириш имконини беради. Mongoose'да схемада index: true ёки schema.index() орқали индекс белгилаш мумкин, бу эса катта коллекцияларда сезиларли ишлаш тезлигини таъминлайди.

NoSQL ва хусусан MongoDB қачон энг мос келади деган савол кўп берилади. Агар маълумотлар тузилиши тез ўзгариб турса, катта ҳажмли ва горизонтал кенгайишни талаб қилса, реал вақтдаги аналитика ёки контент бошқаруви каби вазифалар бўлса, MongoDB ажойиб танловдир. Аксинча, қатъий транзакциялар ва мураккаб JOIN боғланишлар муҳим бўлган молиявий тизимларда анъанавий SQL ҳали ҳам устунликка эга. Тўғри танлов ҳар доим лойиҳа талабларига боғлиқ, ва кўп ҳолларда замонавий иловалар иккала ёндашувни бирга ишлатади.

Хулоса қилиб айтганда, MongoDB ва Mongoose жуфтлиги Node.js дастурчиларига маълумотлар билан табиий, JavaScript услубида ишлаш имконини беради. Схемалар тартиб ўрнатади, валидация ишончлиликни оширади, populate эса боғланишларни соддалаштиради. Ушбу воситаларни ўзлаштирган ҳар бир backend дастурчи маълумотлар базаси билан ишлашни анча самарали ва хавфсиз тарзда олиб боради.

Ўхшаш мақолалар

🌾 Қишлоқ хўжалиги ва агро сайти: маҳсулотлар каталоги ❤️ Хайрия фонди сайти: шаффоф ва ишонч 🎉 Тўйxона ва банкет зали сайти: бирон қилиш 🚙 Автомобил ижара сайти: каталог ва бирон
🌐 Тил
🇺🇿 O'zbek 🇺🇿 Ўзбек 🇷🇺 Русский 🇬🇧 English