Phép chiếu, sắp xếp và giới hạn
Thuộc phần Cơ sở dữ liệu với MongoDB trong hành trình Node.js của Coddy. Bài học 13 trên 29.
Danh sách “sách mới nhất” cần một vài trường từ một vài cuốn sách, theo thứ tự.
Phép chiếu chọn các trường mà truy vấn trả về: 1 giữ lại một trường, còn _id sẽ đi kèm trừ khi bạn đặt thành 0. Trên con trỏ, sort({ field: -1 }) sắp xếp từ cao xuống thấp (1 là từ thấp lên cao), còn limit(n) giữ lại n kết quả đầu tiên.
// 5 điểm số cao nhất, chỉ gồm tên và điểm số
await players
.find({}, { projection: { name: 1, score: 1, _id: 0 } })
.sort({ score: -1 })
.limit(5)
.toArray();Cơ sở dữ liệu sắp xếp trước khi giới hạn, bất kể bạn nối hai lời gọi này theo thứ tự nào. Sắp xếp mảng trong JavaScript sau limit sẽ khiến bạn sắp xếp nhầm 5 kết quả.
Thử thách
DễBước này mở dự án API kệ sách đã chuẩn bị sẵn cho khóa học, chứ không phải các tệp dự án của bạn trong Bộ lọc truy vấn (bao gồm cả server.js). Phần bạn đã làm trước đó vẫn nằm trong bài học riêng. Hãy đọc các tệp được cung cấp trước khi chỉnh sửa server.js. Bản sao này có các route cho kệ sách và bộ lọc khoảng năm.
Trang chủ hiển thị những cuốn sách mới nhất, chỉ gồm tiêu đề và năm xuất bản.
- Trong
server.js, thêm một routeGET /books/newest. Đặt route này phía trênGET /books/:id. Express thử các route theo thứ tự, và/books/:idcũng khớp với/books/newest. Route này sẽ xemnewestlà một id và trả về 400. - Route này trả về các cuốn sách được sắp xếp theo
year, từ cao nhất trở xuống. ?n=cho biết số cuốn sách cần trả về. Nếu thiếun, hãy trả về 3 cuốn.- Mỗi cuốn sách chỉ có
titlevàyear, không có_idhay trường nào khác. Hãy để truy vấn chọn các trường, sắp xếp sách và rút gọn danh sách. Với các cuốn sách có sẵn,GET /books/newest?n=2trả về:Thử nhé: Gửi[ { "title": "Kindred", "year": 1979 }, { "title": "Dune", "year": 1965 } ]GET /books/newest. Bạn sẽ nhận được Kindred (1979), Dune (1965) và Emma (1815), theo thứ tự đó, mỗi cuốn chỉ có tiêu đề và năm xuất bản. GửiGET /books/newest?n=1: bạn sẽ nhận được[ { "title": "Kindred", "year": 1979 } ]. Nếu bạn nhận được 400,GET /books/:idđã nhận yêu cầu, vì vậy hãy chuyển route của bạn lên phía trên nó.
Tự làm thử
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());
// Mọi lỗi đều trả về { 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');
});
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Cơ sở dữ liệu với MongoDB
Tự luyện tập: Playground Express