Menu
CoddyTech

Filtri di query

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

Spesso un client vuole solo alcuni libri e il database può selezionarli.

L'oggetto che passi a find è un filtro: un documento corrisponde quando corrispondono tutti i campi del filtro. Un valore semplice significa uguaglianza. Un operatore è una chiave che inizia con $ ed effettua un confronto: $gte significa maggiore o uguale, $lte minore o uguale. Due operatori sullo stesso campo condividono un oggetto: { total: { $gte: 20, $lte: 50 } } seleziona i totali da 20 a 50.

// ordini pagati di importo pari o superiore a 20
await orders.find({ status: 'paid', total: { $gte: 20 } }).toArray();

I tipi sono importanti: { $gte: '20' } confronta una stringa e MongoDB non abbina mai una stringa a un campo numerico. Tutto ciò che si trova in req.query è una stringa, quindi converti i numeri in valori numerici con Number() prima di inserirli in un filtro.

challenge icon

Sfida

Facile

Questo passaggio apre il progetto API di una libreria preparato per il corso, anziché i file del tuo progetto di Ricerca con ObjectId (incluso server.js). Il lavoro precedente resta nella sua lezione. Leggi i file forniti prima di modificare server.js. Questa copia contiene le route per l'inserimento dei libri nella libreria e per la ricerca tramite ObjectId.

I client vogliono solo alcuni libri: quelli di un autore oppure quelli pubblicati in determinati anni. Lascia che sia il database a selezionarli.

  1. In server.js, modifica GET /books. Crea un oggetto filtro a partire dalla stringa di query e passalo a find. La route continua a rispondere con un array JSON di libri.
  2. ?author=Jane%20Austen restituisce solo i libri il cui author è esattamente Jane Austen. (%20 è il modo in cui un URL rappresenta uno spazio.)
  3. ?from=1960 restituisce i libri con year pari o successivo al 1960. ?to=1980 restituisce i libri del 1980 o degli anni precedenti. Se usi entrambi, un libro deve rientrare nell'intervallo tra i due anni, estremi inclusi. Puoi usare anche uno solo dei due.
  4. I valori della query arrivano sempre come stringhe, ma gli anni memorizzati sono numeri. Converti from e to in numeri prima di inserirli nel filtro, altrimenti non verrà trovato nulla.
  5. Senza query, la route restituisce tutti i libri, come prima. Prova: Invia GET /books?from=1960&to=1980: ottieni Dune (1965) e Kindred (1979). Invia GET /books?from=1970: ottieni solo Kindred. Invia GET /books?to=1900: ottieni solo Emma (1815). Invia GET /books?author=Jane%20Austen: ottieni solo Emma. Invia GET /books: ottieni tutti e tre i libri.

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 list = await books.find().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');
});

Tutte le lezioni di Database con MongoDB

Esercitati da solo: Playground Express