Menu
CoddyTech

Projection, Sort ו-Limit

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

רשימת "הספרים החדשים ביותר" צריכה כמה שדות מכמה ספרים, לפי הסדר.

היטל בוחר את השדות שעליהם השאילתה מחזירה תשובה: 1 משאיר שדה, ו־_id נכלל אלא אם מגדירים אותו ל־0. על הסמן, sort({ field: -1 }) ממיין מהגבוה לנמוך (1 הוא מהנמוך לגבוה), ו־limit(n) משאיר את n התוצאות הראשונות.

// 5 התוצאות הגבוהות ביותר, name ו-score בלבד
await players
    .find({}, { projection: { name: 1, score: 1, _id: 0 } })
    .sort({ score: -1 })
    .limit(5)
    .toArray();

מסד הנתונים ממיין לפני שהוא מגביל את מספר התוצאות, בלי קשר לסדר שבו משרשרים את שתי הקריאות. מיון המערך ב-JavaScript אחרי limit ממיין את חמש התוצאות הלא נכונות.

challenge icon

אתגר

קל

בשלב הזה נפתח פרויקט API מדף הספרים שהוכן עבור הקורס, ולא את קובצי הפרויקט שלך מתוך מסנני שאילתות (כולל server.js). העבודה הקודמת שלך נשארת בשיעור משלה. קרא את הקבצים שסופקו לפני עריכת server.js. העותק הזה מכיל את הנתיבים של מדף הספרים ואת מסנן טווח השנים.

דף הבית מציג את הספרים החדשים ביותר, עם הכותרת והשנה בלבד.

  1. ב־server.js, הוסף נתיב GET /books/newest. הצב אותו מעל GET /books/:id. Express מנסה את הנתיבים לפי הסדר, ו־/books/:id תואם גם ל־/books/newest. הוא יתייחס ל־newest כמזהה וישיב 400.
  2. הנתיב מחזיר ספרים ממוינים לפי year, מהגבוה לנמוך.
  3. ?n= מציין כמה ספרים להחזיר. כש־n חסר, יש להחזיר 3.
  4. כל ספר כולל רק title ו־year, ללא _id וללא שדות אחרים. תן לשאילתה לבחור את השדות, למיין את הספרים ולקצץ את הרשימה. עבור הספרים ההתחלתיים, GET /books/newest?n=2 מחזיר:
    [ { "title": "Kindred", "year": 1979 }, { "title": "Dune", "year": 1965 } ]
    נסה זאת: שלח GET /books/newest. תקבל את Kindred (1979), את Dune (1965) ואת Emma (1815), בסדר הזה, עם כותרת ושנה בלבד לכל ספר. שלח GET /books/newest?n=1: תקבל [ { "title": "Kindred", "year": 1979 } ]. אם מתקבלת תשובת 400, הבקשה טופלה על ידי GET /books/:id, ולכן העבר את הנתיב שלך למיקום שמעליו.

נסו בעצמכם

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 });
}

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/:id', async (req, res) => {
    if (!ObjectId.isValid(req.params.id)) {
        return sendError(res, 400, 'Not a valid id');
    }
    const book = await books.findOne({ _id: new ObjectId(req.params.id) });
    if (!book) {
        return sendError(res, 404, 'No such book');
    }
    res.json(book);
});

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

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

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

תרגלו בעצמכם: Express אונליין