web-dev-qa-db-fra.com

Comment compter tous les documents d'une collection et utiliser le cont dans un contrôleur, avec MongoDB et Express.js?

Je travaille sur une application de blog (cliquez sur le lien pour voir le GitHub repo) avec Express (version 4.17.1), EJS et MongoDB (version 4.0.10).

En essayant de paginer les messages, j'ai fait ce qui suit, dans le contrôleur:

exports.getPosts = (req, res, next) => {

    const perPage = 5;

    const currPage = req.query.page ? parseInt(req.query.page) : 1;

    let postsCount = 0;

    const posts = Post.find({}, (err, posts) => {

            postsCount = posts.length;

            let pageDecrement = currPage > 1 ? 1 : 0;

            let pageIncrement = postsCount >= perPage ? 1 : 0;

            if (err) {
                console.log('Error: ', err);
            } else {
                res.render('default/index', {
                    moment: moment,
                    layout: 'default/layout',
                    website_name: 'MEAN Blog',
                    page_heading: 'XPress News',
                    page_subheading: 'A MEAN Stack Blogging Application',
                    currPage: currPage,
                    posts: posts,
                    pageDecrement: pageDecrement,
                    pageIncrement: pageIncrement
                });
            }
        })
        .sort({
            created_at: -1
        })
        .populate('category')
        .limit(perPage)
        .skip((currPage - 1) * perPage);
};

Et dans la vue:

<a class="btn btn-primary <%= pageDecrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage - pageDecrement %>">&larr; Newer Posts</a>

et

<a class="btn btn-primary <%= pageIncrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage + pageIncrement %>">Older Posts &rarr;</a>

Cela fonctionne bien à moins qu'il y ait un nombre de messages égal à perPage x N, Où N est un entier, auquel cas le bouton "Articles plus anciens" devient désactivé une page trop tard.

C'est parce que postsCount = posts.length Compte les messages après ils sont limités par .skip((currPage - 1) * perPage).

Je dois donc compter les messages du modèle/collection et apporter cette variable de compte in le contrôleur.

Mon modele:

const mongoose = require('mongoose');

const postSchema = new mongoose.Schema({
    title: {
        type: String,
        required: true
    },
    short_description: {
        type: String,
        required: true
    },
    full_text: {
        type: String,
        required: true
    },
    category: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Category'
    },
    post_image: {
        type: String,
        required: false
    },
    updated_at: {
        type: Date,
        default: Date.now()
    },
    created_at: {
        type: Date,
        default: Date.now()
    }
});

module.exports = mongoose.model('Post', postSchema);

Comment compter tous les documents de la collection de messages et utiliser ce nombre dans le contrôleur de messages?

2
Razvan Zamfir

En cas de Mongoose, vous devriez utiliser ceci:

https://mongoosejs.com/docs/api.html#aggregate_Aggregate-facet

Documents officiels Mongodb:

https://docs.mongodb.com/manual/reference/operator/aggregation/facet

L'idée générale est d'effectuer une agrégation au lieu de plusieurs appels (1 pour obtenir les informations nécessaires + 1 pour obtenir le nombre total de documents)

Vous pouvez bien sûr effectuer 2 appels séparés, mais cela affectera vos performances (pas beaucoup pour les petits volumes de données mais quand même ...) Vous pouvez donc obtenir toutes les données nécessaires avec .find () et ensuite obtenir un compte comme ceci: https://mongoosejs.com/docs/api.html#model_Model.count

PS. btw, utilisez async/await au lieu des rappels pour éviter l'enfer des rappels

0
AveCezar17