mongodb如何从集合中获取最大价值

Hos*_*ian 68 max mongodb

我有一个mongodb集合,如:

db.kids.find()
//results
[
    {name:'tom', age:10},
    {name:'alice', age:12},
    ....
]
Run Code Online (Sandbox Code Playgroud)

我需要一个查询来从这个集合中获取MAX'age',就像在SQL中一样: SELECT MAX(age) FROM kids WHERE 1

Hos*_*ian 100

作为评论之一:

db.collection.find().sort({age:-1}).limit(1) // for MAX
db.collection.find().sort({age:+1}).limit(1) // for MIN
Run Code Online (Sandbox Code Playgroud)

它完全可用,但我不确定性能

  • 如果是大型集合,最好在"age"字段中定义索引.然后,如果你使用`db.collection.find({},{年龄:1,_id:0})排序({年龄:-1}).限制(1)',你可能会有一个非常快的所覆盖查询](https://docs.mongodb.com/v3.0/core/query-optimization/#covered-query) (8认同)

小智 59

建议答案的表现很好.根据MongoDB文档:

当$ sort紧接在$ limit之前时,优化器可以将$ limit合并到$ sort中.这允许排序操作仅在进展时保持前n个结果,其中n是指定的限制,而MongoDB只需要在内存中存储n个项目.

所以在这种情况下

db.collection.find().sort({age:-1}).limit(1)
Run Code Online (Sandbox Code Playgroud)

由于上述优化,我们只得到最高元素而没有对集合进行排序.

  • 该文档链接用于汇总。您确定`find(...)。sort(...)。limit(...)`与`aggregate([{{$ match:...},{$ sort:.. 。},{$ limit:...}]))`?他们在mongo文档中有没有提到这一点的地方? (2认同)
  • @jmmut https://docs.mongodb.com/manual/reference/method/cursor.sort/#limit-results (2认同)

小智 14

如何使用聚合框架:

db.collection.aggregate({ $group : { _id: null, max: { $max : "$age" }}});
Run Code Online (Sandbox Code Playgroud)

  • 这不如sort.limit有效.尽管如此,我知道每个人都对这种类型和限制感到奇怪...... (14认同)
  • @tuananh,如果您没有“分数”的索引,则可能会发生这种情况。在这种情况下,排序将必须执行O(n log n)操作,而聚合将仅执行一次扫描O(n)。使用索引字段,sort(...)。limit(1)将是非常快速的恒定时间O(1)操作。 (2认同)

小智 14

您可以使用组和最大值:

db.getCollection('kids').aggregate([
    {
        $group: {
            _id: null,
            maxQuantity: {$max: "$age"}
        }
    }
])
Run Code Online (Sandbox Code Playgroud)


Sum*_*t S 5

伙计们,您可以通过运行计划来查看优化器正在做什么。查看计划的通用格式来自 MongoDB文档。即Cursor.plan()。如果你真的想深入挖掘,你可以做一个cursor.plan(true)了解更多细节。

话虽如此,如果您有一个索引,您db.col.find().sort({"field":-1}).limit(1)将读取一个索引条目 - 即使索引默认为升序,并且您想要集合中的最大条目和一个值。

换句话说,@yogesh 的建议是正确的。

谢谢 - 苏米特