Menu
CoddyTech

Projection, Sort ve Limit

Coddy'nin Node.js Journey'sinin MongoDB ile Veritabanları bölümünün bir parçası. Ders 13 / 29.

"En yeni kitaplar" listesi, birkaç kitaptan birkaç alanı sıralı olarak gerektirir.

Projeksiyon, sorgunun yanıtladığı alanları seçer: 1 bir alanı dahil eder ve _id değerini 0 olarak ayarlamadığınız sürece o da sonuçlara eklenir. İmleç üzerinde sort({ field: -1 }) büyükten küçüğe sıralar (1 küçükten büyüğe sıralar) ve limit(n) ilk n sonucu tutar.

// en yüksek 5 skor, yalnızca name ve score
await players
    .find({}, { projection: { name: 1, score: 1, _id: 0 } })
    .sort({ score: -1 })
    .limit(5)
    .toArray();

İki çağrıyı hangi sırayla zincirlediğinizden bağımsız olarak, veritabanı sınırlamadan önce sıralama yapar. limit sonrasında JavaScript'te diziyi sıralamak, yanlış beş sonucu sıralar.

challenge icon

Görev

Kolay

Bu adım, Query Filters dersindeki proje dosyalarınız yerine kurs için hazırlanmış kitaplık API projesini açar (server.js dâhil). Önceki çalışmalarınız kendi dersinde kalır. server.js dosyasını düzenlemeden önce sağlanan dosyaları okuyun. Bu kopyada kitaplık rotaları ve yıl aralığı filtresi bulunur.

Ana sayfada en yeni kitaplar, yalnızca başlıkları ve yılları gösterilir.

  1. server.js dosyasına bir GET /books/newest rotası ekleyin. Bu rotayı GET /books/:id rotasının üstüne yerleştirin. Express rotaları sırayla dener ve /books/:id rotası /books/newest adresiyle de eşleşir. Bu durumda newest ifadesini bir kimlik olarak değerlendirir ve 400 yanıtı verir.
  2. Rota, kitapları year değerine göre en yüksekten en düşüğe sıralanmış şekilde döndürür.
  3. ?n=, döndürülecek kitap sayısını belirtir. n yoksa 3 kitap döndürün.
  4. Her kitapta yalnızca title ve year bulunmalı; _id veya başka bir alan bulunmamalıdır. Alanları seçmesi, kitapları sıralaması ve listeyi kısaltması için sorguyu kullanın. Başlangıç kitaplarında GET /books/newest?n=2 şu sonucu döndürür:
    [ { "title": "Kindred", "year": 1979 }, { "title": "Dune", "year": 1965 } ]
    Deneyin: GET /books/newest isteğini gönderin. Sırasıyla Kindred (1979), Dune (1965) ve Emma (1815) kitaplarını alırsınız; her kitapta yalnızca bir başlık ve bir yıl bulunur. GET /books/newest?n=1 isteğini gönderin: [ { "title": "Kindred", "year": 1979 } ] sonucunu alırsınız. 400 yanıtı alırsanız isteği GET /books/:id rotası karşılamıştır; bu nedenle rotanızı onun üstüne taşıyın.

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 });
}

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/:id', async (req, res) => {
    if (!ObjectId.isValid(req.params.id)) {
        return sendError(res, 400, 'Not a valid id');
    }
    const book = await books.findOne({ _id: new ObjectId(req.params.id) });
    if (!book) {
        return sendError(res, 404, 'No such book');
    }
    res.json(book);
});

app.listen(3000, () => {
    console.log('Bookshelf is running on port 3000');
});
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

MongoDB ile Veritabanları bölümündeki tüm dersler

Kendi başına pratik yap: Express playground