Aktualizowanie dokumentów
Część sekcji Bazy danych z MongoDB ścieżki Node.js w Coddy. Lekcja 14 z 29.
Poprawienie roku wydania książki powinno zmienić tylko to jedno pole, pozostawiając pozostałe bez zmian.
updateOne(filter, update) zmienia pierwszy dokument pasujący do filtra. Aktualizacja składa się z operatorów: $set zapisuje podane pola i zachowuje wszystkie pozostałe. Zwykły obiekt bez operatora jest odrzucany z komunikatem "Update document requires atomic operators".
const result = await players.updateOne(
{ name: 'Ada' },
{ $set: { score: 120, level: 4 } }
);
result.matchedCount; // 1, jeśli znaleziono pasującego gracza, 0, jeśli nie znaleziono żadnego
result.modifiedCount; // 0, jeśli wartości były już takie sameRozróżnij brak dokumentu od dokumentu, który nie uległ zmianie, za pomocą matchedCount, a nie modifiedCount. Aktualizacja nie zwraca dokumentu, więc odczytaj go ponownie za pomocą findOne.
Wyzwanie
ŁatwyKlient chce poprawić jedno pole książki, na przykład błędny rok, bez ponownego wysyłania całej książki.
- W pliku
server.js, poniżej komentarza// Add PATCH /books/:id here., dodaj trasęPATCH /books/:id. - Rozpocznij ją tak, jak teraz rozpoczyna się
GET /books/:id: wywołajparseId(req, res). Jeśli identyfikator jest nieprawidłowy,parseIdzdążyło już odpowiedzieć kodem 400 i zwracanull, więc zakończ działanie w tym miejscu. - Zmieniaj tylko pola przesłane w treści żądania, a wszystkie pozostałe pozostaw bez zmian. Treść żądania
{ "year": 1966 }zmienia rok i nic więcej. - Jeśli nie ma książki z takim identyfikatorem
_id, odpowiedz kodem statusu 404 i błędem, na przykład{ "error": "No such book" }. - W przeciwnym razie odpowiedz kodem statusu 200 i całą książką w postaci, w jakiej jest teraz zapisana:Wypróbuj: Wyślij
{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1966, "isbn": "9780441013593", "genre": "scifi" }GET /booksi skopiuj_idksiążki Dune. Kopiuj go ponownie po każdym uruchomieniu, ponieważ za każdym razem identyfikatory są nowe. WyślijPATCH /books/wraz z_idksiążki Dune i treścią żądania{ "year": 1966 }. Otrzymasz kod 200 i książkę Dune z"year": 1966; wszystkie pozostałe pola pozostaną bez zmian, a karta Data pokaże to samo. Wyślij to samo żądanie ponownie: nadal otrzymasz kod 200, ponieważ książka istnieje, mimo że tym razem nic się nie zmieniło. WyślijPATCH /books/000000000000000000000000z{ "year": 1966 }: otrzymasz kod 404. WyślijPATCH /books/42: otrzymasz kod 400.
Spróbuj swoich sił
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());
// Każdy błąd zwraca odpowiedź { error: message }.
function sendError(res, status, message) {
res.status(status).json({ error: message });
}
// Wartość :id jako ObjectId albo null po zwróceniu odpowiedzi 400 dla nieprawidłowego id.
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);
});
// Dodaj tutaj PATCH /books/:id.
app.listen(3000, () => {
console.log('Bookshelf is running on port 3000');
});
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Bazy danych z MongoDB
1Dokumenty
Książka jako dokumentKolekcje i bazy danychŁączenie z MongoDBOdczytywanie zapisanych dokumentówWstawianie dokumentówWyszukiwanie jednego dokumentuWyszukiwanie według ObjectIdPorównywanie liczbFiltry zapytańWybieranie zwracanych pólSortowanie wyników zapytaniaOgraniczanie do pierwszych wynikówProjekcja, sortowanie i limit2Modyfikowanie dokumentów
Aktualizowanie dokumentówOperatory aktualizacjiPoćwicz samodzielnie: Edytor online Express