Menu
CoddyTech

Filtros de consulta

Parte de la sección Bases de datos con MongoDB del Journey de Node.js de Coddy. Lección 9 de 29.

Un cliente suele querer solo algunos libros, y la base de datos puede elegirlos.

El objeto que pasas a find es un filtro: un documento coincide cuando coinciden todos los campos del filtro. Un valor simple significa igualdad. Un operador es una clave que empieza con $ y compara de otra manera: $gte significa mayor o igual que, $lte menor o igual que. Dos operadores en el mismo campo comparten un objeto: { total: { $gte: 20, $lte: 50 } } conserva los totales de 20 a 50.

// pedidos pagados de 20 o más
await orders.find({ status: 'paid', total: { $gte: 20 } }).toArray();

Los tipos importan: { $gte: '20' } compara una cadena, y MongoDB nunca hace coincidir una cadena con un campo numérico. Todo lo que hay en req.query es una cadena, así que convierte los números en números con Number() antes de incluirlos en un filtro.

challenge icon

Desafío

Fácil

Este paso abre el proyecto de API de estantería preparado para el curso, en lugar de los archivos de tu proyecto de Búsqueda por ObjectId (incluido server.js). Tu trabajo anterior permanece en su propia lección. Lee los archivos proporcionados antes de editar server.js. Esta copia contiene las rutas para insertar libros en la estantería y buscarlos por ObjectId.

Los clientes solo quieren algunos libros: los libros de un autor o los libros de determinados años. Deja que la base de datos los seleccione.

  1. En server.js, modifica GET /books. Crea un objeto de filtro a partir de la cadena de consulta y pásalo a find. La ruta sigue respondiendo con una matriz JSON de libros.
  2. ?author=Jane%20Austen devuelve solo los libros cuyo author es exactamente Jane Austen. (%20 es la forma en que una URL representa un espacio.)
  3. ?from=1960 devuelve los libros con un year de 1960 o posterior. ?to=1980 devuelve los libros de 1980 o anteriores. Si se especifican ambos, el año del libro debe estar entre esos dos años, que también se incluyen. Se puede usar cualquiera de los dos por separado.
  4. Los valores de consulta siempre llegan como cadenas, pero los años almacenados son números. Convierte from y to en números antes de incluirlos en el filtro; de lo contrario, no habrá coincidencias.
  5. Si no hay ninguna consulta, la ruta devuelve todos los libros, como antes. Pruébalo: Envía GET /books?from=1960&to=1980: obtendrás Dune (1965) y Kindred (1979). Envía GET /books?from=1970: obtendrás solo Kindred. Envía GET /books?to=1900: obtendrás solo Emma (1815). Envía GET /books?author=Jane%20Austen: obtendrás solo Emma. Envía GET /books: obtendrás los tres.

Pruébalo tú mismo

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

// Cada error responde con { 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 las lecciones de Bases de datos con MongoDB

Practica por tu cuenta: Playground de Express