Menu
CoddyTech

Filtres de requête

Fait partie de la section Bases de données avec MongoDB du Journey Node.js de Coddy. Leçon 9 sur 29.

Un client ne veut souvent que certains livres, et la base de données peut faire le tri.

L’objet que tu transmets à find est un filtre : un document correspond lorsque chaque champ du filtre correspond. Une valeur simple signifie « égal à ». Un opérateur est une clé qui commence par $ et effectue une comparaison : $gte signifie « supérieur ou égal à », $lte signifie « inférieur ou égal à ». Deux opérateurs sur le même champ partagent un seul objet : { total: { $gte: 20, $lte: 50 } } conserve les totaux compris entre 20 et 50.

// commandes payées d’un montant de 20 ou plus
await orders.find({ status: 'paid', total: { $gte: 20 } }).toArray();

Les types comptent : { $gte: '20' } compare une chaîne, et MongoDB ne fait jamais correspondre une chaîne à un champ numérique. Tout ce qui se trouve dans req.query est une chaîne ; convertis donc les nombres en nombres avec Number() avant de les intégrer à un filtre.

challenge icon

Défi

Facile

Cette étape ouvre le projet d’API de bibliothèque préparé pour le cours, plutôt que les fichiers de ton projet de Recherche par ObjectId (y compris server.js). Ton travail précédent reste dans sa propre leçon. Lis les fichiers fournis avant de modifier server.js. Cette copie contient les routes d’insertion de livres dans la bibliothèque et de recherche par ObjectId.

Les clients ne veulent que certains livres : les livres d’un auteur, ou ceux publiés pendant certaines années. Laisse la base de données les sélectionner.

  1. Dans server.js, modifie GET /books. Construis un objet de filtre à partir de la chaîne de requête et transmets-le à find. La route renvoie toujours un tableau JSON de livres.
  2. ?author=Jane%20Austen renvoie uniquement les livres dont la valeur de author est exactement Jane Austen. (%20 est la façon dont une URL représente une espace.)
  3. ?from=1960 renvoie les livres dont year est égal ou supérieur à 1960. ?to=1980 renvoie les livres publiés en 1980 ou avant. Si les deux sont indiqués, un livre doit se situer entre ces deux années, qui sont incluses. L’un ou l’autre peut être utilisé seul.
  4. Les valeurs des paramètres de requête arrivent toujours sous forme de chaînes, mais les années enregistrées sont des nombres. Convertis from et to en nombres avant de les inclure dans le filtre, sinon aucun résultat ne correspondra.
  5. Sans paramètre de requête, la route renvoie tous les livres, comme auparavant. Essaie : Envoie GET /books?from=1960&to=1980 : tu obtiens Dune (1965) et Kindred (1979). Envoie GET /books?from=1970 : tu obtiens uniquement Kindred. Envoie GET /books?to=1900 : tu obtiens uniquement Emma (1815). Envoie GET /books?author=Jane%20Austen : tu obtiens uniquement Emma. Envoie GET /books : tu obtiens les trois livres.

Essayez vous-même

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

// Chaque erreur renvoie { 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');
});

Toutes les leçons de Bases de données avec MongoDB

Entraînez-vous par vous-même : Playground Express