Cập nhật 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 14 trên 29.
Việc sửa năm xuất bản của một cuốn sách chỉ nên thay đổi trường đó và giữ nguyên các trường khác.
updateOne(filter, update) thay đổi tài liệu đầu tiên khớp với bộ lọc. Bản cập nhật gồm các toán tử: $set ghi các trường bạn cung cấp và giữ nguyên mọi trường khác. Một đối tượng thông thường không có toán tử sẽ bị từ chối với thông báo "Update document requires atomic operators".
const result = await players.updateOne(
{ name: 'Ada' },
{ $set: { score: 120, level: 4 } }
);
result.matchedCount; // 1 nếu tìm thấy người chơi khớp, 0 nếu không
result.modifiedCount; // 0 nếu các giá trị đã giống nhauDùng matchedCount, không phải modifiedCount, để phân biệt tài liệu không tồn tại với tài liệu không có gì thay đổi. Bản cập nhật không trả về tài liệu, nên hãy đọc lại bằng findOne.
Thử thách
DễKhách hàng muốn sửa một trường của sách, chẳng hạn như năm xuất bản bị sai, mà không gửi lại toàn bộ thông tin sách.
- Trong
server.js, bên dưới chú thích// Add PATCH /books/:id here., thêm một tuyếnPATCH /books/:id. - Bắt đầu giống như cách
GET /books/:idhiện đang bắt đầu: gọiparseId(req, res). Nếu id không hợp lệ,parseIdđã phản hồi với mã 400 và trả vềnull, vì vậy hãy dừng tại đó. - Chỉ thay đổi những trường mà phần thân yêu cầu, còn mọi trường khác giữ nguyên. Phần thân
{ "year": 1966 }sẽ đổi năm và không thay đổi gì khác. - Nếu không có sách nào mang
_idđó, hãy phản hồi với mã trạng thái 404 và một lỗi, ví dụ{ "error": "No such book" }. - Nếu không, hãy phản hồi với mã trạng thái 200 và toàn bộ thông tin sách như hiện được lưu:Thử ngay: Gửi
{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1966, "isbn": "9780441013593", "genre": "scifi" }GET /booksvà sao chép_idcủa Dune. Sao chép lại sau mỗi lần bấm Chạy, vì mỗi lần chạy sẽ tạo id mới. GửiPATCH /books/kèm theo_idcủa Dune, với phần thân{ "year": 1966 }. Bạn nhận được mã 200 và thông tin Dune với"year": 1966, mọi trường khác đều giữ nguyên, và tab Data cũng hiển thị như vậy. Gửi lại cùng yêu cầu: bạn vẫn nhận được mã 200, vì sách vẫn tồn tại dù lần này không có gì thay đổi. GửiPATCH /books/000000000000000000000000với{ "year": 1966 }: bạn nhận được mã 404. GửiPATCH /books/42: bạn nhận được mã 400.
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ề 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);
});
// Thêm PATCH /books/:id vào đây.
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