Güncelleme Operatörleri
Coddy'nin Node.js Journey'sinin MongoDB ile Veritabanları bölümünün bir parçası. Ders 15 / 29.
Bir kopya veya etiket eklemek, kitabı okumadan, JavaScript'te değiştirip yeniden yazmadan yerinde değiştirmelidir.
$inc, bir alana sayı ekler; alan yoksa 0'dan başlar. $push, bir dizi alanına değer ekler; alan yoksa diziyi oluşturur. Tek bir güncelleme birkaç işleç içerebilir:
await players.updateOne(
{ name: 'Ada' },
{ $inc: { wins: 1 }, $push: { badges: 'streak' } }
);Değişikliği veritabanı kendisi uygular, bu yüzden aynı anda yapılan iki isteğin ikisi de sayılır. $set burada uygun değildir: badges dizisinin tamamını verdiğiniz değerle değiştirir.
Görev
KolayKitaplık, sahip olduğunuz her kitabın kaç kopyası olduğunu sayar ve okuyucular kitaplara etiket ekleyebilir. Her iki değişiklik de kitabı önce okumadan, veritabanının içinde tek bir güncellemeyle gerçekleşir.
server.jsdosyasınaPOST /books/:id/copiesekleyin. İstek gövdesi gerekmez. Kitabıncopiesalanına 1 ekler. Henüzcopiesalanı olmayan bir kitabın değeri"copies": 1olur.POST /books/:id/tagsekleyin. İstek gövdesinde bir etiket belirtilir; örneğin{ "tag": "classic" }. Rota, etiketi kitabıntagslistesinin sonuna ekler ve listedeki mevcut etiketleri korur. Henüztagsalanı olmayan bir kitabın değeri"tags": ["classic"]olur.- Her iki rota da geçersiz bir kimlik için
parseIdkullanır ve 400 yanıtı verir. Belirtilen_iddeğerine sahip bir kitap yoksa her iki rota da 404 yanıtı verir. Aksi hâlde her ikisi de 200 durum kodu ve güncellenmiş kitabın tamamıyla yanıt verir. İki kopya ve önceclassic, ardındanfavoriteetiketleri eklendikten sonra Dune şöyle görünür:Deneyin:{ "_id": "6720a1f4c2b9e81d3a5f0c11", "title": "Dune", "author": "Frank Herbert", "year": 1965, "isbn": "9780441013593", "genre": "scifi", "copies": 2, "tags": ["classic", "favorite"] }GET /booksisteği gönderin ve Dune'un_iddeğerini kopyalayın. Boş bir istek gövdesiylePOST /books/<Dune's _id>/copiesisteği gönderin:"copies": 1olan Dune yanıtını alırsınız. İsteği tekrar gönderin:"copies": 2.{ "tag": "classic" }gövdesiylePOST /books/<Dune's _id>/tagsisteği gönderin:"tags": ["classic"]. Bu kez{ "tag": "favorite" }gövdesiyle tekrar gönderin:"tags": ["classic", "favorite"].POST /books/000000000000000000000000/copiesisteği gönderin: 404 yanıtı alırsınız.
Kendin dene
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());
// Her hata { error: message } biçiminde yanıt verir.
function sendError(res, status, message) {
res.status(status).json({ error: message });
}
// :id değerini ObjectId olarak döndürür; geçersiz bir id için 400 yanıtı verdikten sonra null döndürür.
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');
});
MongoDB ile Veritabanları bölümündeki tüm dersler
2Belgeleri Değiştirme
Belgeleri GüncellemeGüncelleme OperatörleriKendi başına pratik yap: Express playground