العثور باستخدام ObjectId
جزء من قسم قواعد البيانات باستخدام MongoDB في رحلة Node.js على Coddy. الدرس 7 من 29.
للإجابة عن طلب كتاب واحد، يبحث الخادم عنه باستخدام _id، لكن المعرّف يصل في عنوان URL على هيئة نص.
إن _id الذي ينشئه MongoDB هو ObjectId: قيمة من 12 بايت مكتوبة على هيئة 24 محرفًا سداسيًا عشريًا: الأرقام من 0 إلى 9 والحروف من a إلى f. يعرضه JSON كسلسلة نصية، لكنه ليس كذلك في قاعدة البيانات، لذا فإن مرشحًا يستخدم النص العادي لا يطابق أي شيء. حوّل النص أولًا إلى ObjectId. يحدد ObjectId.isValid ما إذا كان النص يمكن أن يكون قيمة من هذا النوع، لأن new ObjectId يطلق استثناءً عند إعطائه أي شيء آخر.
import { ObjectId } from 'mongodb';
const text = '66f1c2a9e4b0a1b2c3d4e5f6';
await orders.findOne({ _id: new ObjectId(text) }); // الطلب، أو null
await orders.findOne({ _id: text }); // null: text ليس ObjectId
ObjectId.isValid('42'); // falseتعيد findOne أول مستند مطابق، أو null عندما لا يوجد أي مستند مطابق.
التحدي
سهلتفتح هذه الخطوة مشروع Bookshelf API المُعَدّ للدورة، وليس ملفات مشروعك من درس إدراج المستندات (بما فيها server.js). يبقى عملك السابق في درسه الخاص. اقرأ الملفات المرفقة قبل تعديل server.js. تحتوي هذه النسخة على مسارات قائمة الكتب وإضافتها.
يريد عميل كتابًا واحدًا، يحدده _id الخاص به.
- أضف مسارًا من نوع
GET /books/:idفيserver.js. - المعرّف الموجود في عنوان URL هو نص. بعض النصوص لا يمكن أبدًا أن تكون ObjectId، وهو مكوّن من 24 حرفًا من الأرقام والحروف من a إلى f. بالنسبة إلى هذا النص، أرسل استجابة برمز الحالة 400 وخطأ، باستخدام
sendError، مثل{ "error": "Not a valid id" }. تحقّق من ذلك قبل إنشاء ObjectId، لأن إنشاءه من نص غير صالح يؤدي إلى خطأ. - وإلا، فابحث عن الكتاب باستخدام
_idالخاص به. عندما تجده، أرسل استجابة برمز الحالة 200 والكتاب:{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1965, "isbn": "9780441013593", "genre": "scifi" }. - إذا لم يكن هناك كتاب بهذا
_id، فأرسل استجابة برمز الحالة 404 وخطأ، مثل{ "error": "No such book" }. جرّب ذلك: أرسلGET /booksوانسخ_idالخاص بكتاب Dune: الأحرف الأربعة والعشرين التي تأتي بعد"_id":. يمنح كل تشغيل الكتب معرّفات جديدة، لذا انسخه مرة أخرى بعد كل تشغيل. أرسلGET /books/متبوعًا بالمعرّف الذي نسخته: ستحصل على 200 وكتاب Dune. أرسلGET /books/42: ستحصل على 400. أرسلGET /books/000000000000000000000000: إنه معرّف صالح لا يخص أي كتاب، لذا ستحصل على 404.
جرّب بنفسك
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());
// كل خطأ يُرجع { 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');
});
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس قواعد البيانات باستخدام MongoDB
تدرّب بنفسك: Playground لـ Express