Ricerca tramite ObjectId
Fa parte della sezione Database con MongoDB del percorso Node.js di Coddy. Lezione 7 di 29.
Per recuperare un libro, il server lo cerca tramite _id, ma l’id arriva nell’URL come testo.
Un _id creato da MongoDB è un ObjectId: un valore di 12 byte scritto con 24 caratteri esadecimali: le cifre da 0 a 9 e le lettere da a a f. JSON lo mostra come stringa, ma nel database non lo è, quindi un filtro con il semplice testo non trova nulla. Converti prima il testo in un ObjectId. ObjectId.isValid indica se un testo può essere un ObjectId, perché new ObjectId genera un errore per qualsiasi altro valore.
import { ObjectId } from 'mongodb';
const text = '66f1c2a9e4b0a1b2c3d4e5f6';
await orders.findOne({ _id: new ObjectId(text) }); // l'ordine, oppure null
await orders.findOne({ _id: text }); // null: text non è un ObjectId
ObjectId.isValid('42'); // falsefindOne restituisce il primo documento corrispondente, oppure null se non ne trova nessuno.
Sfida
FacileQuesto passaggio apre il progetto API di libreria preparato per il corso, anziché i file del tuo progetto di Inserimento di documenti (incluso server.js). Il lavoro svolto in precedenza rimane nella sua lezione. Leggi i file forniti prima di modificare server.js. Questa copia contiene le route per elencare e inserire libri.
Un client vuole un libro, scelto in base al suo _id.
- In
server.js, aggiungi una routeGET /books/:id. - L’id nell’URL è testo. Alcune stringhe non possono mai essere un ObjectId, che è composto da 24 caratteri: cifre e lettere dalla a alla f. Per quel testo, rispondi con lo stato 400 e un errore, usando
sendError, per esempio{ "error": "Not a valid id" }. Esegui questo controllo prima di creare un ObjectId, perché crearne uno a partire da testo non valido genera un errore. - Altrimenti, cerca il libro in base al suo
_id. Quando lo trovi, rispondi con lo stato 200 e il libro:{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1965, "isbn": "9780441013593", "genre": "scifi" }. - Se nessun libro ha quell’
_id, rispondi con lo stato 404 e un errore, per esempio{ "error": "No such book" }. Prova: inviaGET /bookse copia l’_iddi Dune: i 24 caratteri dopo"_id":. A ogni esecuzione, i libri ricevono nuovi ID, quindi copialo di nuovo dopo ogni esecuzione. InviaGET /books/seguito dall’ID che hai copiato: riceverai 200 e Dune. InviaGET /books/42: riceverai 400. InviaGET /books/000000000000000000000000: è un ID valido che nessun libro ha, quindi riceverai 404.
Provalo tu
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());
// Ogni errore restituisce { 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');
});
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Database con MongoDB
1Documenti
Un libro come documentoRaccolte e databaseConnessione a MongoDBLettura dei documenti memorizzatiInserimento di documentiRicerca di un documentoRicerca tramite ObjectIdConfronto tra numeriFiltri di queryScelta dei campi restituitiOrdinamento dei risultati della queryMantenere i primi risultatiProiezione, ordinamento e limiteEsercitati da solo: Playground Express