简体   繁体   中英

Count Documents in mongoose in single query

const postsCount = await Post.find(query).countDocuments();
const allPosts = await Post.find(query)
      .populate('likes')
      .skip(startIndex)
      .limit(noOfRecordsPerPage)
      .sort({ createdAt: 'desc' });

I am querying two times in Database to find the total document count . How can i do this with a single query to the database ?

//you can use aggregation pipeline and $facet to combine two DB requests into one
//Actual Code output from windows Mongoshell/Command Line Interface(CLI)
> print("mongoDB",db.version())
mongoDB 4.2.6
> db.groups1.aggregate([
... {$facet:{
...   "docCount":[
...     {$group:{
...       _id:null,
...       count:{$sum:1}
...       }
...      }
...     ],
...   "allDocs":[
...      {$match:{}}
...      ]
...  }
...  }
... ]).pretty();
{
        "docCount" : [
                {
                        "_id" : null,
                        "count" : 4
                }
        ],
        "allDocs" : [
                {
                        "_id" : ObjectId("5f817d142689512ef0bd3bd7"),
                        "uid" : 1,
                        "group_id" : "g1"
                },
                {
                        "_id" : ObjectId("5f817d142689512ef0bd3bd8"),
                        "uid" : 1,
                        "group_id" : "g2"
                },
                {
                        "_id" : ObjectId("5f817d142689512ef0bd3bd9"),
                        "uid" : 2,
                        "group_id" : "g2"
                },
                {
                        "_id" : ObjectId("5f817d142689512ef0bd3bd1"),
                        "uid" : 2,
                        "group_id" : "g3"
                }
        ]
}
>

Use the $facet aggregation stage to combine multiple nested pipelines into your master pipeline.

Here's a working code of the above idea -

const countPipeline = [
    {
        $match: query
    },
    {
        $group: {
            _id: null,
            count: {
                $sum: 1
            }
        }
    },
    {
        $project: {
            _id: 0,
            count: '$count'
        }
    }
];

const postPipeline = [
    {
        $match: query
    },
    {
        $skip: startIndex
    },
    {
        $limit: noOfRecordsPerPage
    },
    {
        $sort: {
            createdAt: -1
        }
    }
];

const pipeline = [
    {
        $facet: {
            posts: postPipeline,
            count: countPipeline
        }
    }
];

const results = await Posts.aggreagate(pipeline).exec();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM