Aggiornamento dei documenti
Fa parte della sezione Database con MongoDB del percorso Node.js di Coddy. Lezione 14 di 29.
Correggere l'anno di un libro dovrebbe modificare quel campo e lasciare invariati gli altri.
updateOne(filter, update) modifica il primo documento che corrisponde al filtro. L'aggiornamento è composto da operatori: $set scrive i campi che gli indichi e mantiene tutti gli altri. Un oggetto semplice senza operatori viene rifiutato con "Update document requires atomic operators".
const result = await players.updateOne(
{ name: 'Ada' },
{ $set: { score: 120, level: 4 } }
);
result.matchedCount; // 1 se un giocatore corrispondeva, 0 se nessuno corrispondeva
result.modifiedCount; // 0 se i valori erano già gli stessiUsa matchedCount, non modifiedCount, per distinguere un documento mancante da uno invariato. L'aggiornamento non restituisce il documento, quindi rileggilo con findOne.
Sfida
FacileUn cliente vuole correggere un campo di un libro, per esempio un anno errato, senza inviare di nuovo l'intero libro.
- In
server.js, sotto il commento// Add PATCH /books/:id here., aggiungi una routePATCH /books/:id. - Avviala come inizia ora
GET /books/:id: chiamaparseId(req, res). Se l'id non è valido,parseIdha già risposto con 400 e restituiscenull, quindi fermati lì. - Modifica solo i campi inviati nel body e lascia invariati tutti gli altri. Un body
{ "year": 1966 }modifica l'anno e nient'altro. - Se non esiste alcun libro con quel
_id, rispondi con lo status 404 e un errore, per esempio{ "error": "No such book" }. - Altrimenti, rispondi con lo status 200 e l'intero libro così come è salvato ora:Prova: invia
{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1966, "isbn": "9780441013593", "genre": "scifi" }GET /bookse copia l'_iddi Dune. Copialo di nuovo dopo ogni esecuzione, perché ogni esecuzione genera nuovi ID. InviaPATCH /books/seguito dall'_iddi Dune, con il body{ "year": 1966 }. Ricevi 200 e Dune con"year": 1966, mentre tutti gli altri campi restano invariati; anche la scheda Data mostra lo stesso risultato. Invia di nuovo la stessa richiesta: ricevi ancora 200, perché il libro esiste anche se questa volta non è cambiato nulla. InviaPATCH /books/000000000000000000000000con{ "year": 1966 }: ricevi 404. InviaPATCH /books/42: ricevi 400.
Provalo tu
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());
// Ogni errore restituisce { error: message }.
function sendError(res, status, message) {
res.status(status).json({ error: message });
}
// Il parametro :id come ObjectId, oppure null dopo aver restituito 400 per un id non valido.
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);
});
// Aggiungi PATCH /books/:id qui.
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 limite2Modifica dei documenti
Aggiornamento dei documentiOperatori di aggiornamentoEsercitati da solo: Playground Express