Tìm theo ObjectId
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 7 trên 29.
Để tìm một sách, máy chủ tra cứu theo _id, nhưng id trong URL lại ở dạng văn bản.
_id do MongoDB tạo là một ObjectId: giá trị 12 byte được viết bằng 24 ký tự thập lục phân, gồm các chữ số từ 0 đến 9 và các chữ cái từ a đến f. JSON hiển thị nó dưới dạng chuỗi, nhưng trong cơ sở dữ liệu thì không phải vậy, nên bộ lọc dùng văn bản thuần sẽ không khớp với gì cả. Trước tiên, hãy chuyển văn bản thành ObjectId. ObjectId.isValid cho biết văn bản có thể là một ObjectId hay không, vì new ObjectId sẽ gây lỗi với mọi giá trị khác.
import { ObjectId } from 'mongodb';
const text = '66f1c2a9e4b0a1b2c3d4e5f6';
await orders.findOne({ _id: new ObjectId(text) }); // đơn hàng hoặc null
await orders.findOne({ _id: text }); // null: text không phải là ObjectId
ObjectId.isValid('42'); // falsefindOne trả về tài liệu đầu tiên khớp, hoặc null nếu không có tài liệu nào khớp.
Thử thách
DễBước này mở dự án API kệ sách đã được chuẩn bị cho khóa học, thay vì các tệp dự án của bạn từ Chèn tài liệu (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. Đọc các tệp được cung cấp trước khi chỉnh sửa server.js. Bản này có các route liệt kê và chèn sách.
Ứng dụng khách muốn lấy một cuốn sách theo _id.
- Trong
server.js, thêm một routeGET /books/:id. - Id trong URL là văn bản. Một số văn bản không thể là ObjectId, vốn gồm 24 ký tự là chữ số và các chữ cái từ a đến f. Với văn bản đó, hãy phản hồi bằng trạng thái 400 và một lỗi, dùng
sendError, ví dụ{ "error": "Not a valid id" }. Kiểm tra điều này trước khi tạo ObjectId, vì tạo ObjectId từ văn bản không hợp lệ sẽ gây lỗi. - Nếu không, hãy tìm sách theo
_id. Khi tìm thấy sách, hãy phản hồi bằng trạng thái 200 và cuốn sách:{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1965, "isbn": "9780441013593", "genre": "scifi" }. - Nếu không có cuốn sách nào mang
_idđó, hãy phản hồi bằng trạng thái 404 và một lỗi, ví dụ{ "error": "No such book" }. Thử nhé: GửiGET /booksvà sao chép_idcủa Dune: 24 ký tự sau"_id":. Mỗi lần nhấn Chạy, sách sẽ có id mới, vì vậy hãy sao chép lại sau mỗi lần chạy. GửiGET /books/theo sau là id bạn đã sao chép: bạn sẽ nhận được trạng thái 200 và Dune. GửiGET /books/42: bạn sẽ nhận được trạng thái 400. GửiGET /books/000000000000000000000000: đây là id hợp lệ nhưng không thuộc về cuốn sách nào, vì vậy bạn sẽ nhận được trạng thái 404.
Tự làm thử
import express from 'express';
import { MongoClient } 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 list = await books.find().toArray();
res.json(list);
});
app.post('/books', async (req, res) => {
const book = req.body;
await books.insertOne(book);
res.status(201).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