Menu
CoddyTech

Proyección, ordenación y límite

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

Una lista de los «libros más recientes» necesita unos cuantos campos de unos cuantos libros, en orden.

Una proyección elige los campos que devuelve una consulta: 1 conserva un campo, y _id se incluye a menos que lo establezcas en 0. En el cursor, sort({ field: -1 }) ordena de mayor a menor (1 ordena de menor a mayor), y limit(n) conserva los primeros n resultados.

// las 5 puntuaciones más altas, solo el nombre y la puntuación
await players
    .find({}, { projection: { name: 1, score: 1, _id: 0 } })
    .sort({ score: -1 })
    .limit(5)
    .toArray();

La base de datos ordena antes de limitar, sin importar el orden en que encadenes las dos llamadas. Ordenar el arreglo en JavaScript después de limit ordena los cinco resultados equivocados.

challenge icon

Desafío

Fácil
  • GET /books/newest devuelve primero los libros más recientes, cada uno solo como { "title", "year" }.
  • ?n= indica cuántos; si no se especifica, 3.
  • Decláralo antes de GET /books/:id, o newest se interpretará como un id.

Envía GET /books/newest y después GET /books/newest?n=1.

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 devuelve { 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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Bases de datos con MongoDB