MongoDB Academy · Lektion

Forbindelse med den officielle Node.js-driver

De lærende vil oprette en MongoClient, administrere forbindelsespoolen og køre CRUD-handlinger fra en Node.js-applikation ved hjælp af den native driver.

Lektion 1 af 413 trin

Forbindelse med den officielle Node.js-driver er en gratis MongoDB Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i MongoDB Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. MongoDB Academy-kurset indeholder 4 lektioner i alt.

Den officielle MongoDB Node.js-driver

MongoDB Node.js-driveren (npm-pakken mongodb) er det officielle bibliotek på lavt niveau til at oprette forbindelse til MongoDB fra Node.js-applikationer. Den giver direkte adgang til alle MongoDB-funktioner uden et abstraktionslag, hvilket gør den velegnet til ydeevnekritisk kode, mikrotjenester og scripts. Driveren vedligeholdes af MongoDB, Inc. og følger tæt med i nye funktioner på MongoDB-serveren.

// Install the driver
// npm install mongodb

// Or with yarn:
// yarn add mongodb

// The driver exports MongoClient as its main entry point
const { MongoClient, ObjectId, ServerApiVersion } = require('mongodb');
// or ES module:
// import { MongoClient, ObjectId } from 'mongodb';

Oprettelse af en MongoClient

Klassen MongoClient er indgangspunktet for alle interaktioner. Opret en instans med din forbindelsesstreng (URI) og et valgfrit options-objekt. Forbindelsesstrengen indeholder vært, port, legitimationsoplysninger og forbindelsesparametre. For MongoDB Atlas skal du kopiere forbindelsesstrengen fra Atlas-brugergrænsefladen og erstatte pladsholderadgangskoden. Opret én MongoClient pr. applikation, og genbrug den – opret ikke en ny for hver forespørgsel.

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

const uri = process.env.MONGODB_URI;
// URI format: mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true

const client = new MongoClient(uri, {
  serverApi: {
    version: ServerApiVersion.v1,
    strict: true,
    deprecationErrors: true
  }
});

// client is not yet connected — connecting happens lazily or via connect()

Oprettelse af forbindelse til MongoDB

Kald client.connect() for at oprette en forbindelsespool. Driveren vedligeholder en forbindelsespool – typisk 5-100 forbindelser til serveren – og genbruger dem på tværs af handlinger. Du behøver kun at kalde connect() én gang ved opstart af applikationen. Handlinger kan også kaldes direkte uden et eksplicit connect() – driveren opretter forbindelsen løbende ved den første handling. Kald client.close(), når applikationen lukkes ned.

async function main() {
  try {
    await client.connect();
    console.log('Connected to MongoDB');

    // Get database reference
    const db = client.db('myDatabase');
    
    // Ping the server to verify connection
    await db.command({ ping: 1 });
    console.log('Ping successful');

    // Run your application logic here...
  } finally {
    // Always close when done
    await client.close();
  }
}

main().catch(console.error);

Singleton-mønster til webservere

I en webserver (Express, Fastify, NestJS) skal MongoClient være en singleton på modulniveau, der oprettes én gang ved opstart og deles af alle anmodningsbehandlere. Hvis du opretter en ny MongoClient for hver anmodning, opbruger du de tilgængelige forbindelser og forringer ydeevnen alvorligt. Det almindelige mønster er at oprette forbindelse i serverens opstartsfunktion og eksportere klienten eller db-referencen.

// db.js — module-level singleton
const { MongoClient } = require('mongodb');

let client;
let db;

async function connectToDatabase() {
  if (db) return db; // return existing connection
  client = new MongoClient(process.env.MONGODB_URI);
  await client.connect();
  db = client.db(process.env.DB_NAME || 'myapp');
  return db;
}

module.exports = { connectToDatabase };

// In your Express app:
// const { connectToDatabase } = require('./db');
// const db = await connectToDatabase();
// app.locals.db = db;

Hentning af samlingsreferencer

Få adgang til en samling ved at kalde db.collection('collectionName'). Det returnerer et Collection-objekt uden netværkskald – det er blot en reference. Du kan hente samlingsreferencer ved opstart og gemme dem som variabler på modulniveau eller hente dem direkte i hver funktion. Samlingsreferencer er lette og kan genbruges sikkert på tværs af anmodninger.

const db = client.db('ecommerce');

// Get collection references
const usersCollection = db.collection('users');
const ordersCollection = db.collection('orders');
const productsCollection = db.collection('products');

// TypeScript: provide a document type for type safety
// const users = db.collection<UserDocument>('users');

// Collections can also be retrieved inline:
async function getUser(id) {
  return client.db('ecommerce').collection('users').findOne({ _id: id });
}

CRUD-handlinger: Indsættelse

Indsæt dokumenter med insertOne() eller insertMany(). Driveren genererer automatisk et _id, hvis det ikke er angivet, og returnerer de indsatte id'er. Resultatobjektets insertedId (for insertOne) eller insertedIds-kort (for insertMany) gør det muligt at holde styr på, hvad der blev oprettet. Begge handlinger accepterer et options-objekt, hvor du kan angive writeConcern.

const db = client.db('shop');
const products = db.collection('products');

// Insert one document
const insertResult = await products.insertOne({
  name: 'Mechanical Keyboard',
  price: 149.99,
  category: 'Electronics',
  stock: 50
});
console.log('Inserted ID:', insertResult.insertedId);

// Insert multiple documents
const bulkResult = await products.insertMany([
  { name: 'Mouse Pad', price: 19.99, category: 'Accessories' },
  { name: 'USB Hub', price: 39.99, category: 'Electronics' }
]);
console.log('Inserted count:', bulkResult.insertedCount);

CRUD-handlinger: Læsning

Brug findOne(filter) til at hente ét dokument eller find(filter) til at få en cursor over alle matchende dokumenter. Konvertér en cursor til et array med .toArray() ved små resultatsæt, eller gennemløb den med for await...of ved store resultatsæt. Begge metoder accepterer et andet options-argument til projection, sort, skip, limit og andre forespørgselsmodifikatorer.

const users = db.collection('users');

// Find a single user by email
const user = await users.findOne(
  { email: 'alice@example.com' },
  { projection: { password: 0 } }  // exclude sensitive fields
);

// Find multiple documents with options
const activeUsers = await users.find(
  { active: true, role: 'admin' },
  {
    projection: { name: 1, email: 1 },
    sort: { createdAt: -1 },
    limit: 50
  }
).toArray();

// Iterate large results without loading all into memory
const cursor = users.find({ active: true });
for await (const user of cursor) {
  await processUser(user);
}

CRUD-handlinger: Opdatering

Opdatér dokumenter med updateOne(), updateMany() eller findOneAndUpdate(). Filteret udvælger, hvilke dokumenter der skal opdateres, og opdateringsdokumentet angiver ændringerne ved hjælp af operatorer som $set, $inc og $push. updateOne() og updateMany() returnerer et resultat med matchedCount og modifiedCount. Brug upsert: true til at oprette dokumentet, hvis det ikke findes.

const orders = db.collection('orders');

// Update one order's status
const updateResult = await orders.updateOne(
  { _id: orderId },
  { $set: { status: 'shipped', shippedAt: new Date() } }
);
console.log('Modified:', updateResult.modifiedCount);

// Atomic: find, update, and return the updated document
const updatedOrder = await orders.findOneAndUpdate(
  { _id: orderId },
  { $set: { status: 'delivered' }, $push: { statusHistory: { status: 'delivered', at: new Date() } } },
  { returnDocument: 'after' }  // return the document AFTER update
);

CRUD-handlinger: Sletning

Slet dokumenter med deleteOne() eller deleteMany(). Filteret bestemmer, hvilke dokumenter der skal fjernes. Resultatet indeholder deletedCount. Af sikkerhedshensyn i produktion skal du altid teste dit filter med find, før du kører deleteMany – utilsigtet sletning af alle dokumenter i en samling er en almindelig og katastrofal fejl. Overvej logisk sletning (ved at angive feltet deletedAt) i stedet for fysisk sletning, hvis du har brug for revisionsspor.

const sessions = db.collection('sessions');

// Delete one session
const deleteResult = await sessions.deleteOne({ _id: sessionId });
console.log('Deleted:', deleteResult.deletedCount);

// Delete all expired sessions — test filter first!
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);

// 1. Test: how many would be deleted?
const count = await sessions.countDocuments({ expiresAt: { $lt: thirtyDaysAgo } });
console.log('Would delete:', count);

// 2. Only delete after confirming the count looks right
if (count < 10000) { // sanity check
  await sessions.deleteMany({ expiresAt: { $lt: thirtyDaysAgo } });
}

Kørsel af aggregeringsforløb

Udfør aggregeringsforløb med collection.aggregate(pipeline). Det returnerer en cursor, som du kan konvertere til et array eller gennemløbe. Forløbets trin sendes som et array af objekter. Driveren sender forløbet til MongoDB's aggregeringsmotor og streamer resultaterne tilbage. Ved meget store resultatsæt skal du gennemløbe cursoren direkte i stedet for at kalde .toArray(), så du undgår at indlæse alt i hukommelsen på én gang.

const orders = db.collection('orders');

// Revenue report by category
const report = await orders.aggregate([
  { $match: { status: 'completed', createdAt: { $gte: new Date('2024-01-01') } } },
  { $group: { _id: '$category', total: { $sum: '$amount' }, count: { $sum: 1 } } },
  { $sort: { total: -1 } }
]).toArray();

console.log('Revenue report:', report);

// For large aggregations, iterate the cursor:
const cursor = orders.aggregate([...largeComplexPipeline]);
for await (const doc of cursor) {
  await writeToReport(doc);
}

Konfiguration af forbindelsespool

MongoClient vedligeholder en forbindelsespool, der automatisk administrerer forbindelserne til serveren. Vigtige indstillinger er: maxPoolSize (maksimalt antal forbindelser, som standard 5 pr. vært), minPoolSize (minimum, der holdes i live), connectTimeoutMS og socketTimeoutMS. Ved API'er med meget trafik kan du øge maxPoolSize, men afvej det mod MongoDB's hukommelsesforbrug pr. forbindelse. Overvåg poolens udnyttelse ved hjælp af Atlas-metrikker.

const client = new MongoClient(uri, {
  maxPoolSize: 20,           // max 20 connections to the server
  minPoolSize: 5,            // keep at least 5 connections warm
  connectTimeoutMS: 5000,   // fail fast if can't connect in 5s
  socketTimeoutMS: 45000,   // idle socket timeout
  serverSelectionTimeoutMS: 5000  // how long to wait to find an available server
});

Hurtigt tjek

Test din forståelse af begreberne fra denne lektion om MongoDB og NoSQL-databaser.

Opsummering af lektionen

I denne lektion har du lært, at du skal oprette én MongoClient ved opstart og genbruge den som singleton – opret aldrig én pr. anmodning, hente referencer til databaser og samlinger med client.db() og db.collection() – det er lette objektreferencer, og bruge insertOne/insertMany, findOne/find, updateOne/updateMany/findOneAndUpdate og deleteOne/deleteMany til CRUD-handlinger. Næste gang undersøger vi Mongoose-skemaer, modeller og virtuals som et abstraktionslag på højere niveau oven på den native driver.

Gratis at komme i gang

Lær JavaScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Forbindelse med den officielle Node.js-driver” gratis?

Ja — hele teksten til “Forbindelse med den officielle Node.js-driver” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af MongoDB Academy-kurset, skal du opgradere til CoddyKit PRO. MongoDB Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Forbindelse med den officielle Node.js-driver”?

De lærende vil oprette en MongoClient, administrere forbindelsespoolen og køre CRUD-handlinger fra en Node.js-applikation ved hjælp af den native driver. Du øver dig i MongoDB Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på MongoDB Academy?

Der kræves ingen tidligere erfaring. MongoDB Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Forbindelse med den officielle Node.js-driver”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne MongoDB Academy-lektion?

Ja. Alle MongoDB Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Forbindelse med den officielle Node.js-driver
  2. Mongoose-skemaer, modeller og virtuals
  3. Mongoose-forespørgsler, kædning og lean-dokumenter
  4. Mongoose-middleware: før- og efter-hooks
← Tilbage til MongoDB Academy