Menu
CoddyTech

Filtros de consulta

Parte da seção Bancos de dados com MongoDB do Journey de Node.js da Coddy. Lição 9 de 29.

Um cliente muitas vezes quer apenas alguns livros, e o banco de dados pode fazer essa seleção.

O objeto que você passa para find é um filtro: um documento corresponde quando todos os campos do filtro correspondem. Um valor simples significa igualdade. Um operador é uma chave que começa com $ e faz uma comparação: $gte significa maior ou igual, $lte significa menor ou igual. Dois operadores no mesmo campo compartilham um objeto: { total: { $gte: 20, $lte: 50 } } mantém os totais de 20 a 50.

// pedidos pagos de 20 ou mais
await orders.find({ status: 'paid', total: { $gte: 20 } }).toArray();

Os tipos importam: { $gte: '20' } compara uma string, e o MongoDB nunca encontra correspondência entre uma string e um campo numérico. Tudo em req.query é uma string, então converta os números em números com Number() antes de colocá-los em um filtro.

challenge icon

Desafio

Fácil

Esta etapa abre o projeto da API de estante de livros preparado para o curso, em vez dos arquivos do seu projeto de Finding by ObjectId (incluindo server.js). Seu trabalho anterior continua na própria lição. Leia os arquivos fornecidos antes de editar server.js. Esta cópia contém as rotas de inserção de livros na estante e de busca por ObjectId.

Os clientes querem apenas alguns livros: os livros de um autor ou os livros de determinados anos. Deixe o banco de dados selecioná-los.

  1. Em server.js, altere GET /books. Crie um objeto de filtro a partir da string de consulta e passe-o para find. A rota continua respondendo com um array JSON de livros.
  2. ?author=Jane%20Austen retorna apenas os livros cujo author é exatamente Jane Austen. (%20 é a forma como uma URL representa um espaço.)
  3. ?from=1960 retorna os livros com year igual ou posterior a 1960. ?to=1980 retorna os livros de 1980 ou anteriores. Quando ambos são informados, o livro deve estar entre os dois anos, incluindo os próprios anos. Qualquer um deles pode ser informado sozinho.
  4. Os valores de consulta sempre chegam como strings, mas os anos armazenados são números. Converta from e to em números antes de colocá-los no filtro, caso contrário nada corresponderá.
  5. Sem consulta, a rota retorna todos os livros, como antes. Teste: Envie GET /books?from=1960&to=1980: você recebe Dune (1965) e Kindred (1979). Envie GET /books?from=1970: você recebe apenas Kindred. Envie GET /books?to=1900: você recebe apenas Emma (1815). Envie GET /books?author=Jane%20Austen: você recebe apenas Emma. Envie GET /books: você recebe os três.

Experimente você mesmo

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

// Todo erro retorna { 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');
});

Todas as lições de Bancos de dados com MongoDB

Pratique por conta própria: Playground de Express