0Pricing
MongoDB Academy · درس

تهيئة البيانات باستخدام نصوص Node.js

سيكتب المتعلمون نص تهيئة بيانات باستخدام Node.js يقرأ ملف JSON ويدرج المستندات دفعة واحدة في MongoDB لأغراض التطوير المحلي.

تهيئة البيانات باستخدام نصوص Node.js درس مجاني في MongoDB Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في MongoDB Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة MongoDB Academy 4 دروس في المجموع.

بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.

Why Write a Seed Script?

A seed script is a Node.js program that populates a MongoDB database with initial or test data. Unlike mongoimport, a seed script can generate dynamic data (IDs, relationships, timestamps), conditionally insert data that doesn't already exist, and apply business logic while seeding—for example, hashing passwords or computing derived fields. Seed scripts are the backbone of local development environment setup.

Setting Up the MongoDB Client

A seed script connects to MongoDB using the official mongodb Node.js driver. Keep the connection URI in an environment variable or a .env file—never hardcode credentials. Call client.connect() at the start, run all seed operations, and call client.close() in a finally block to ensure the script exits cleanly even if an error occurs.

const { MongoClient, ObjectId } = require('mongodb');

const URI = process.env.MONGO_URI || 'mongodb://localhost:27017';
const DB_NAME = 'myapp';

async function seed() {
  const client = new MongoClient(URI);
  try {
    await client.connect();
    console.log('Connected to MongoDB');
    const db = client.db(DB_NAME);
    await seedUsers(db);
    await seedProducts(db);
    console.log('Seeding complete!');
  } finally {
    await client.close();
  }
}

seed().catch(console.error);

Inserting Documents With bulkWrite

Use collection.bulkWrite() with ordered: false for efficient bulk inserts. Unlike multiple insertOne calls, bulkWrite sends all operations to the server in a single network round trip. Set ordered: false so that duplicate key errors on individual documents don't stop the entire batch—useful when re-running a seed script that uses deterministic IDs.

async function seedUsers(db) {
  const users = [
    { _id: new ObjectId('aaa000000000000000000001'), name: 'Alice', email: 'alice@example.com', role: 'admin' },
    { _id: new ObjectId('aaa000000000000000000002'), name: 'Bob',   email: 'bob@example.com',   role: 'user'  },
    { _id: new ObjectId('aaa000000000000000000003'), name: 'Carol', email: 'carol@example.com', role: 'user'  }
  ];

  const ops = users.map(u => ({ insertOne: { document: u } }));
  const result = await db.collection('users').bulkWrite(ops, { ordered: false });
  console.log('Users inserted:', result.insertedCount);
}

Idempotent Seeding With deleteMany

Make your seed script idempotent—safe to run multiple times—by clearing the target collections before inserting. Call deleteMany({}) (or drop()) at the start of each seed function. This ensures the database starts from a known clean state on every run, which is essential for local development where you want reproducible data without duplicates.

async function seedProducts(db) {
  const col = db.collection('products');

  // Clear existing data first — idempotent
  await col.deleteMany({});
  console.log('Cleared products collection');

  const products = generateProducts(50); // generate 50 sample products
  await col.insertMany(products);
  console.log('Inserted', products.length, 'products');
}

Generating Realistic Fake Data

For development seeds, generate realistic-looking data programmatically using a helper library like @faker-js/faker or by constructing data manually. Generating data in the script (rather than loading static JSON files) lets you easily change the volume—seed 10 documents for unit tests, 10,000 for load testing—with a single parameter change.

function generateProducts(count) {
  const categories = ['electronics', 'clothing', 'tools', 'books'];
  return Array.from({ length: count }, (_, i) => ({
    _id: new ObjectId(),
    sku: 'PROD-' + String(i + 1).padStart(4, '0'),
    name: 'Product ' + (i + 1),
    price: parseFloat((Math.random() * 100 + 1).toFixed(2)),
    category: categories[i % categories.length],
    rating: parseFloat((Math.random() * 2 + 3).toFixed(1)), // 3.0 - 5.0
    isActive: true,
    createdAt: new Date(Date.now() - i * 86400000) // staggered dates
  }));
}

Seeding Relationships Between Collections

When seeding related collections, create parent documents first and use their _id values when creating child documents. Using deterministic ObjectIds (constructed from fixed hex strings) lets you reference specific parent documents reliably across runs without having to query for them after insertion.

const USER_ID_ALICE = new ObjectId('aaa000000000000000000001');
const USER_ID_BOB   = new ObjectId('aaa000000000000000000002');

async function seedOrders(db) {
  await db.collection('orders').deleteMany({});
  const orders = [
    { userId: USER_ID_ALICE, total: 49.99,  status: 'delivered', createdAt: new Date() },
    { userId: USER_ID_BOB,   total: 120.00, status: 'pending',   createdAt: new Date() }
  ];
  await db.collection('orders').insertMany(orders);
  console.log('Orders seeded');
}

Reading Seed Data From JSON Files

For complex seed data that is easier to maintain as JSON (product catalogues, country lists, configuration tables), read the JSON file with fs.readFileSync and pass the parsed array directly to insertMany. Pair this with the idempotent deleteMany approach so the script can be re-run safely after editing the JSON file.

const fs  = require('fs');
const path = require('path');

async function seedFromFile(db, collectionName, filePath) {
  const raw  = fs.readFileSync(path.resolve(filePath), 'utf-8');
  const docs = JSON.parse(raw);

  const col = db.collection(collectionName);
  await col.deleteMany({});
  await col.insertMany(docs);
  console.log('Seeded', docs.length, 'documents into', collectionName);
}

// Usage
await seedFromFile(db, 'countries', './seed-data/countries.json');

Creating Indexes After Seeding

Seed scripts should create the same indexes that production uses. Call collection.createIndex() (or createIndexes()) at the end of each seed function, or in a dedicated ensureIndexes step. Creating indexes after bulk insert is faster than maintaining them during the insert—MongoDB builds the B-tree from the sorted data in one pass.

async function ensureIndexes(db) {
  // Products: fast category lookups and rating sorts
  await db.collection('products').createIndex({ category: 1, rating: -1 });
  await db.collection('products').createIndex({ sku: 1 }, { unique: true });

  // Orders: fast user-based queries
  await db.collection('orders').createIndex({ userId: 1, createdAt: -1 });

  console.log('Indexes created');
}

Running the Seed Script

Run the seed script from the command line with node seed.js or add it to your package.json scripts section. Pass environment-specific URIs via environment variables so the same script works for local, CI, and staging environments without modification. Never run a seed script that calls deleteMany against a production URI.

// package.json scripts
// {
//   "scripts": {
//     "seed": "node scripts/seed.js",
//     "seed:test": "MONGO_URI=mongodb://localhost:27017 node scripts/seed.js"
//   }
// }

// Run with:
// npm run seed
// or
// MONGO_URI='mongodb://localhost:27017' node scripts/seed.js

Using Seed Scripts in CI Pipelines

In a CI pipeline, run the seed script as part of the test setup step before executing integration or end-to-end tests. Spin up a MongoDB Docker container (or use mongodb-memory-server), run the seed script to populate test data, run the tests, and tear down the container. This gives every CI run a clean, reproducible database state.

# GitHub Actions step example
# - name: Start MongoDB
#   run: docker run -d -p 27017:27017 mongo:7

# - name: Seed test data
#   run: node scripts/seed.js
#   env:
#     MONGO_URI: mongodb://localhost:27017

# - name: Run integration tests
#   run: npm test
#   env:
#     MONGO_URI: mongodb://localhost:27017

Handling Seed Errors Gracefully

Wrap your seed functions in try/catch blocks so that a failure in one section doesn't leave the database in a half-seeded state without a clear error message. Log the error, abort the remaining seed steps, and exit with a non-zero code so CI pipelines detect the failure. A partial seed is often worse than no seed because it produces misleading test results.

async function seed() {
  const client = new MongoClient(process.env.MONGO_URI);
  try {
    await client.connect();
    const db = client.db('myapp');
    await seedUsers(db);
    await seedProducts(db);
    await seedOrders(db);
    await ensureIndexes(db);
    console.log('All seed steps completed successfully');
    process.exit(0);
  } catch (err) {
    console.error('Seed failed:', err.message);
    process.exit(1);
  } finally {
    await client.close();
  }
}

Quick Check

Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.

Lesson Recap

In this lesson you learned: seed scripts use the Node.js driver to insert, clear, and regenerate test data programmatically, deterministic ObjectIds make cross-collection relationships reproducible across runs, and calling deleteMany at the start of each seed function makes the script idempotent and safe to re-run. This completes the Importing and Exporting Data course — next we advance to Indexes Fundamentals for production-grade query performance.

الأسئلة الشائعة

هل درس «تهيئة البيانات باستخدام نصوص Node.js» مجاني؟

نعم — نص درس «تهيئة البيانات باستخدام نصوص Node.js» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة MongoDB Academy، انتقل إلى CoddyKit PRO. تتضمن دورة MongoDB Academy 4 دروس في المجموع.

ماذا ستتعلم في «تهيئة البيانات باستخدام نصوص Node.js»؟

سيكتب المتعلمون نص تهيئة بيانات باستخدام Node.js يقرأ ملف JSON ويدرج المستندات دفعة واحدة في MongoDB لأغراض التطوير المحلي. تتمرن على MongoDB Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ MongoDB Academy؟

لا تُشترط خبرة سابقة. MongoDB Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تهيئة البيانات باستخدام نصوص Node.js»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس MongoDB Academy هذا؟

نعم. كل درس في MongoDB Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. mongoimport: تحميل ملفات JSON وCSV
  2. mongoexport: تصدير المجموعات إلى ملفات
  3. ‏mongodump وmongorestore للنسخ الاحتياطي الكامل
  4. تهيئة البيانات باستخدام نصوص Node.js
← العودة إلى MongoDB Academy