Menu
CoddyTech

Proiezione, ordinamento e limite

Fa parte della sezione Database con MongoDB del percorso Node.js di Coddy. Lezione 13 di 29.

Un elenco dei «libri più recenti» richiede alcuni campi di alcuni libri, in un ordine preciso.

Una proiezione seleziona i campi a cui risponde una query: 1 mantiene un campo e _id viene incluso, a meno che tu non lo imposti a 0. Sul cursore, sort({ field: -1 }) ordina dal valore più alto al più basso (1 ordina dal più basso al più alto) e limit(n) mantiene i primi n risultati.

// i 5 punteggi più alti, solo name e score
await players
    .find({}, { projection: { name: 1, score: 1, _id: 0 } })
    .sort({ score: -1 })
    .limit(5)
    .toArray();

Il database ordina prima di limitare, indipendentemente dall’ordine in cui concateni le due chiamate. Ordinare l’array in JavaScript dopo limit significa ordinare i cinque risultati sbagliati.

challenge icon

Sfida

Facile

Questo passaggio apre il progetto API per la libreria preparato nel corso, anziché i file del tuo progetto di Filtri di query (incluso server.js). Il lavoro precedente rimane nella sua lezione. Leggi i file forniti prima di modificare server.js. Questa copia contiene le route della libreria e il filtro per intervallo di anni.

La pagina iniziale mostra i libri più recenti, con solo il titolo e l’anno.

  1. In server.js, aggiungi una route GET /books/newest. Inseriscila sopra GET /books/:id. Express prova le route nell’ordine e anche /books/:id corrisponde a /books/newest. Tratterebbe newest come un id e risponderebbe con 400.
  2. La route restituisce i libri ordinati per year, dal valore più alto al più basso.
  3. ?n= indica quanti libri restituire. Se n non è specificato, restituisci 3.
  4. Ogni libro contiene solo title e year, senza _id e senza altri campi. Lascia che la query selezioni i campi, ordini i libri e limiti l’elenco. Per i libri iniziali, GET /books/newest?n=2 restituisce:
    [ { "title": "Kindred", "year": 1979 }, { "title": "Dune", "year": 1965 } ]
    Prova: invia GET /books/newest. Ottieni Kindred (1979), Dune (1965) ed Emma (1815), in quest’ordine, ciascuno con solo un titolo e un anno. Invia GET /books/newest?n=1: ottieni [ { "title": "Kindred", "year": 1979 } ]. Se ricevi 400, la richiesta è stata gestita da GET /books/:id, quindi sposta la tua route sopra di essa.

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

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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Database con MongoDB

Esercitati da solo: Playground Express