Operator Pembaruan
Termasuk bagian Database dengan MongoDB dalam perjalanan Node.js di Coddy. Pelajaran 15 dari 29.
Menambahkan salinan atau tag seharusnya mengubah buku secara langsung, tanpa membacanya, mengubahnya di JavaScript, lalu menulisnya kembali.
$inc menambahkan angka ke sebuah field, dimulai dari 0 jika field tersebut tidak ada. $push menambahkan nilai ke akhir field array, membuat array tersebut jika belum ada. Satu pembaruan dapat memuat beberapa operator:
await players.updateOne(
{ name: 'Ada' },
{ $inc: { wins: 1 }, $push: { badges: 'streak' } }
);Database menerapkan perubahan itu sendiri, sehingga dua permintaan yang terjadi pada saat yang sama sama-sama dihitung. $set tidak cocok di sini: operator ini mengganti seluruh array badges dengan nilai yang kamu berikan.
Tantangan
MudahRak menghitung jumlah salinan setiap buku yang kamu miliki, dan pembaca dapat menambahkan tag pada buku. Kedua perubahan terjadi di dalam database, masing-masing dengan satu pembaruan, tanpa membaca buku terlebih dahulu.
- Di
server.js, tambahkanPOST /books/:id/copies. Rute ini tidak memerlukan body. Rute ini menambahkan 1 ke fieldcopiespada buku. Buku yang belum memilikicopiesakan berakhir dengan"copies": 1. - Tambahkan
POST /books/:id/tags. Body menentukan satu tag, misalnya{ "tag": "classic" }. Rute ini menambahkan tag ke akhir listtagspada buku dan mempertahankan tag yang sudah ada. Buku yang belum memilikitagsakan berakhir dengan"tags": ["classic"]. - Kedua rute menggunakan
parseIduntuk id yang tidak valid, dan akan menghasilkan 400. Keduanya merespons dengan 404 jika tidak ada buku dengan_idtersebut. Jika tidak, keduanya merespons dengan status 200 dan seluruh buku yang telah diperbarui. Setelah dua salinan dan tagclassiclalufavorite, Dune akan terlihat seperti ini:Coba: Kirim{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1965, "isbn": "9780441013593", "genre": "scifi", "copies": 2, "tags": ["classic", "favorite"] }GET /booksdan salin_idmilik Dune. KirimPOST /books/<Dune's _id>/copiesdengan body kosong: kamu akan mendapatkan Dune dengan"copies": 1. Kirim sekali lagi:"copies": 2. KirimPOST /books/<Dune's _id>/tagsdengan{ "tag": "classic" }:"tags": ["classic"]. Kirim sekali lagi dengan{ "tag": "favorite" }:"tags": ["classic", "favorite"]. KirimPOST /books/000000000000000000000000/copies: kamu akan mendapatkan 404.
Coba sendiri
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());
// Setiap error menghasilkan respons { error: message }.
function sendError(res, status, message) {
res.status(status).json({ error: message });
}
// Menghasilkan :id sebagai ObjectId, atau null setelah mengirim respons 400 untuk id yang tidak valid.
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);
});
app.patch('/books/:id', async (req, res) => {
const id = parseId(req, res);
if (!id) return;
const result = await books.updateOne({ _id: id }, { $set: req.body });
if (result.matchedCount === 0) {
return sendError(res, 404, 'No such book');
}
res.json(await books.findOne({ _id: id }));
});
app.listen(3000, () => {
console.log('Bookshelf is running on port 3000');
});
Semua pelajaran di Database dengan MongoDB
1Dokumen
Buku sebagai DokumenKoleksi dan DatabaseMenghubungkan ke MongoDBMembaca Dokumen TersimpanMenyisipkan DokumenMenemukan Satu DokumenMenemukan Dokumen berdasarkan ObjectIdMembandingkan AngkaFilter QueryMemilih Field yang DikembalikanMengurutkan Hasil QueryMempertahankan Hasil PertamaProyeksi, Pengurutan, dan BatasLatihan sendiri: Playground Express