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 ממיין את חמש התוצאות הלא נכונות.
אתגר
קלבשלב הזה נפתח פרויקט API מדף הספרים שהוכן עבור הקורס, ולא את קובצי הפרויקט שלך מתוך מסנני שאילתות (כולל server.js). העבודה הקודמת שלך נשארת בשיעור משלה. קרא את הקבצים שסופקו לפני עריכת server.js. העותק הזה מכיל את הנתיבים של מדף הספרים ואת מסנן טווח השנים.
דף הבית מציג את הספרים החדשים ביותר, עם הכותרת והשנה בלבד.
- ב־
server.js, הוסף נתיבGET /books/newest. הצב אותו מעלGET /books/:id. Express מנסה את הנתיבים לפי הסדר, ו־/books/:idתואם גם ל־/books/newest. הוא יתייחס ל־newestכמזהה וישיב 400. - הנתיב מחזיר ספרים ממוינים לפי
year, מהגבוה לנמוך. ?n=מציין כמה ספרים להחזיר. כש־nחסר, יש להחזיר 3.- כל ספר כולל רק
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');
});
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה מסדי נתונים עם MongoDB
תרגלו בעצמכם: Express אונליין