Menu
CoddyTech

עדכון מסמכים

חלק מהיחידה מסדי נתונים עם MongoDB במסלול ה-Node.js של Coddy. שיעור 6 מתוך 18.

תיקון השנה של ספר אמור לשנות את השדה הזה בלבד ולהשאיר את שאר השדות ללא שינוי.

updateOne(filter, update) משנה את המסמך הראשון שתואם למסנן. העדכון מורכב מאופרטורים: $set כותב את השדות שמציינים ומשאיר את כל שאר השדות ללא שינוי. אובייקט רגיל ללא אופרטור נדחה עם ההודעה "Update document requires atomic operators".

const result = await players.updateOne(
    { name: 'Ada' },
    { $set: { score: 120, level: 4 } }
);
result.matchedCount;  // 1 אם נמצאה התאמה לשחקן, 0 אם לא נמצאה התאמה
result.modifiedCount; // 0 אם הערכים כבר היו זהים

הבחינו בין מסמך חסר למסמך שלא השתנה באמצעות matchedCount, ולא באמצעות modifiedCount. העדכון לא מחזיר את המסמך, לכן קראו אותו שוב באמצעות findOne.

challenge icon

אתגר

קל
  • PATCH /books/:id משנה רק את השדות בגוף הבקשה ומחזיר 200 עם הספר המעודכן.
  • מזהה לא מוכר מחזיר 404. הפונקציה parseId שבקוד ההתחלתי כבר מחזירה 400 עבור מזהה שגוי.

שלחו PATCH /books/<id> עם { "year": 1966 } וצפו בספר בכרטיסייה Data.

נסו בעצמכם

import express from 'express';
import { MongoClient, ObjectId } from 'mongodb';

const client = new MongoClient('mongodb://localhost:27017');
const db = client.db('shelf');
const books = db.collection('books');

await books.insertMany([
    { title: 'Dune', author: 'Frank Herbert', year: 1965, isbn: '9780441013593', genre: 'scifi' },
    { title: 'Kindred', author: 'Octavia E. Butler', year: 1979, isbn: '9780807083697', genre: 'scifi' },
    { title: 'Emma', author: 'Jane Austen', year: 1815, isbn: '9780141439587', genre: 'classic' },
]);

const app = express();
app.use(express.json());

// כל שגיאה מחזירה { error: message }.
function sendError(res, status, message) {
    res.status(status).json({ error: message });
}

// מחזירה את :id בתור ObjectId, או null לאחר החזרת 400 עבור id לא תקין.
function parseId(req, res) {
    if (ObjectId.isValid(req.params.id)) {
        return new ObjectId(req.params.id);
    }
    sendError(res, 400, 'Not a valid id');
    return null;
}

app.get('/', (req, res) => {
    res.send('Bookshelf API');
});

app.get('/books', async (req, res) => {
    const filter = {};
    if (req.query.author) {
        filter.author = req.query.author;
    }
    if (req.query.from || req.query.to) {
        filter.year = {};
        if (req.query.from) {
            filter.year.$gte = Number(req.query.from);
        }
        if (req.query.to) {
            filter.year.$lte = Number(req.query.to);
        }
    }
    const list = await books.find(filter).toArray();
    res.json(list);
});

app.post('/books', async (req, res) => {
    const book = req.body;
    await books.insertOne(book);
    res.status(201).json(book);
});

app.get('/books/newest', async (req, res) => {
    const n = Number(req.query.n) || 3;
    const list = await books
        .find({}, { projection: { title: 1, year: 1, _id: 0 } })
        .sort({ year: -1 })
        .limit(n)
        .toArray();
    res.json(list);
});

app.get('/books/:id', async (req, res) => {
    const id = parseId(req, res);
    if (!id) return;
    const book = await books.findOne({ _id: id });
    if (!book) {
        return sendError(res, 404, 'No such book');
    }
    res.json(book);
});

// הוסיפו כאן PATCH /books/:id.

app.listen(3000, () => {
    console.log('Bookshelf is running on port 3000');
});
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה מסדי נתונים עם MongoDB