最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - find and count in single mongodb query - Stack Overflow

programmeradmin5浏览0评论

My documents looks like this.

{
"_id" : ObjectId("572c4bffd073dd581edae045"),
"name" : "What's New in PHP 7",
"description" : "PHP 7 is the first new major version number of PHP since 2004. This course shows what's new, and what's changed.",
"difficulty_level" : "Beginner",
"type" : "Normal",
"tagged_skills" : [ 
    {
        "_id" : "5714e894e09a0f7d804b2254",
        "name" : "PHP"
    }
],
"created_at" : 1462520831.649,
"updated_at" : 1468233074.243    }

Is it possible to get recent 5 documents and total count in a single query. I am using two queries for this requirement as given below.

db.course.find().sort({created_at:-1}).limit(5)
db.course.count()

My documents looks like this.

{
"_id" : ObjectId("572c4bffd073dd581edae045"),
"name" : "What's New in PHP 7",
"description" : "PHP 7 is the first new major version number of PHP since 2004. This course shows what's new, and what's changed.",
"difficulty_level" : "Beginner",
"type" : "Normal",
"tagged_skills" : [ 
    {
        "_id" : "5714e894e09a0f7d804b2254",
        "name" : "PHP"
    }
],
"created_at" : 1462520831.649,
"updated_at" : 1468233074.243    }

Is it possible to get recent 5 documents and total count in a single query. I am using two queries for this requirement as given below.

db.course.find().sort({created_at:-1}).limit(5)
db.course.count()
Share Improve this question asked Aug 4, 2016 at 10:54 jarry jaferyjarry jafery 1,0361 gold badge15 silver badges26 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 7

This is a perfect job for the aggregation framework.

db.course.aggregate(
    [
        { "$sort": { "created_at": -1 }},
        { "$group": {
            "_id": null, 
            "docs": { "$push": "$$ROOT" }, 
            "count": { "$sum": 1 }
        }},
        { "$project": { "_id": 0, "count": 1, "docs": { "$slice": [ "$docs", 5 ] } }}
    ]
)

If your MongoDB server doesn't support $slice then you need to use the ugly and inefficient approach.

db.course.aggregate(
    [
        { "$sort": { "created_at": -1 }},
        { "$group": {
            "_id": null, 
            "docs": { "$push": "$$ROOT" }, 
            "count": { "$sum": 1 }
        }},
        { "$unwind": "$docs" },
        { "$limit": 5 }
    ]
)

You can implement this easily with $facet

myCollection.aggregate([
    {
      $facet: {
        count: [{ $count: "value" }],
        data: [{ $sort: { _id: -1 } }, { $skip: skip }, { $limit: limit }]
      }
    },
    { $unwind: "$count" },
    { $set: { count: "$count.value" } }
])

the return result will be like:

[
  {
    "count": 234,
    "data": [
      // ...
    ]
  }
]

@styvane I tested in person, this query is even less efficient than twice queries.

// get count 
db.course.aggregate([{$match:{}}, {$count: "count"}]);
    // get docs
db.course.aggregate(
       [
            {$match:{}},
            { "$sort": { "created_at": -1 }},
            {"$skip": offset},
            {"$limit": limit}
        ]
)

No, there is no other way. Two queries - one for count - one with limit.

发布评论

评论列表(0)

  1. 暂无评论