Xóa tài liệu
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 16 trên 29.
Xóa một cuốn sách chỉ cần một lần gọi, nhưng máy chủ vẫn phải cho máy khách biết có cuốn sách nào để xóa hay không.
deleteOne(filter) xóa tài liệu đầu tiên khớp với điều kiện lọc và trả về { deletedCount }: 1 nếu đã xóa một tài liệu, 0 nếu không có tài liệu nào khớp. Khi xóa thành công, máy chủ trả về 204 No Content, một trạng thái không có nội dung phản hồi, bằng cách gọi res.status(204).end().
const result = await sessions.deleteOne({ token });
if (result.deletedCount === 0) {
// không có phiên nào mang token đó
}Xóa cùng một id hai lần không nên thành công cả hai lần. Đến lần thứ hai thì không còn gì để xóa, và máy khách cần nhận được 404.
Thử thách
DễMáy khách có thể xóa một cuốn sách và cần biết có cuốn sách nào để xóa hay không.
- Trong
server.js, thêm một tuyếnDELETE /books/:id. DùngparseIdkhi id không hợp lệ, trường hợp này trả về 400. - Khi tuyến xóa một cuốn sách, hãy trả về trạng thái 204 và hoàn toàn không có nội dung phản hồi. Kết thúc phản hồi mà không gửi JSON.
- Khi không có cuốn sách nào mang
_idđó, hãy trả về trạng thái 404 cùng một lỗi, chẳng hạn{ "error": "No such book" }. Vì vậy, nếu xóa cùng một cuốn sách lần thứ hai, kết quả cũng là 404 vì cuốn sách đã bị xóa. Thử xem: GửiGET /booksvà sao chép_idcủa Emma. GửiDELETE /books/<Emma's _id>: bạn nhận được 204 và nội dung phản hồi trống. Gửi lại cùng yêu cầu: bạn nhận được 404. GửiGET /books/<Emma's _id>: bạn cũng nhận được 404. GửiGET /books: bạn chỉ nhận được Dune và Kindred, còn thẻ Dữ liệu hiển thị hai cuốn sách. Nhấn Chạy để đưa Emma trở lại.
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 });
}
// Trả về :id dưới dạng ObjectId, hoặc null sau khi trả về mã 400 nếu id không hợp lệ.
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);
});
app.patch('/books/:id', async (req, res) => {
const id = parseId(req, res);
if (!id) return;
const result = await books.updateOne({ _id: id }, { $set: req.body });
if (result.matchedCount === 0) {
return sendError(res, 404, 'No such book');
}
res.json(await books.findOne({ _id: id }));
});
app.post('/books/:id/copies', async (req, res) => {
const id = parseId(req, res);
if (!id) return;
const result = await books.updateOne({ _id: id }, { $inc: { copies: 1 } });
if (result.matchedCount === 0) {
return sendError(res, 404, 'No such book');
}
res.json(await books.findOne({ _id: id }));
});
app.post('/books/:id/tags', async (req, res) => {
const id = parseId(req, res);
if (!id) return;
const result = await books.updateOne({ _id: id }, { $push: { tags: req.body.tag } });
if (result.matchedCount === 0) {
return sendError(res, 404, 'No such book');
}
res.json(await books.findOne({ _id: id }));
});
app.listen(3000, () => {
console.log('Bookshelf is running on port 3000');
});
Tất cả bài học trong Cơ sở dữ liệu với MongoDB
Tự luyện tập: Playground Express