mongodb如何从集合中获取最大值
Posted
技术标签:
【中文标题】mongodb如何从集合中获取最大值【英文标题】:mongodb how to get max value from collections 【发布时间】:2015-11-11 14:59:16 【问题描述】:我有一个 mongodb 集合,例如:
db.kids.find()
//results
[
name:'tom', age:10,
name:'alice', age:12,
....
]
我需要查询才能从此集合中获取 MAX 'age'
就像在 SQL 中一样:SELECT MAX(age) FROM kids WHERE 1
【问题讨论】:
mongodb: finding the highest numeric value of a column 的可能重复项 你可以使用db.collection.find().sort(age:-1).limit(1)
【参考方案1】:
As one of comments:
db.collection.find().sort(age:-1).limit(1) // for MAX
db.collection.find().sort(age:+1).limit(1) // for MIN
它完全可用,但我不确定性能
【讨论】:
如果集合很大,最好在age
字段上定义一个索引。那么如果你使用db.collection.find(, age: 1, _id:0).sort(age:-1).limit(1)
,你可能会有一个非常快的Covered Query
@AliDehghani 这种方法适用于 mongo 分片吗?
它的工作,谢谢【参考方案2】:
建议答案的表现很好。根据MongoDB documentation:
当 $sort 紧接在 $limit 之前,优化器可以将 $limit 合并到 $sort 中。这允许排序操作 只保留前 n 个结果,其中 n 是 指定的限制,MongoDB只需要存储n个项目 记忆。
在 4.0 版中更改。
所以在
的情况下db.collection.find().sort(age:-1).limit(1)
由于提到的优化,我们只得到最高元素没有对集合进行排序。
【讨论】:
该文档链接用于聚合。您确定find( ... ).sort( ... ).limit( ... )
的处理方式与aggregate([$match: ... , $sort: ..., $limit: ...])
相同吗?他们在 mongo 文档中有提到这一点的地方吗?
@jmmut docs.mongodb.com/manual/reference/method/cursor.sort/…【参考方案3】:
如何使用聚合框架:
db.collection.aggregate( $group : _id: null, max: $max : "$age" );
【讨论】:
这不如 sort.limit 高效。不过,我知道在内心深处,每个人都对这种类型和限制感到奇怪...... @AFP_555 知道聚合比排序限制查询要慢真的很惊讶。感谢分享! 聚合比排序限制查询慢? 我做简单的测试用例。创建一个包含 1,000,000 个文档 name: "player", score: x 的集合。 .find().sort(score:-1).limit(1);花费的时间比 .aggregate([ $group : _id: null, max: $max : "$score" ]) @tuananh,如果您没有关于“分数”的索引,可能会发生这种情况。在这种情况下,排序必须执行 O(n log n) 操作,而聚合将只执行一次扫描 O(n)。使用索引字段, sort(...).limit(1) 将是非常快的常数时间 O(1) 操作。【参考方案4】:你可以使用组和最大值:
db.getCollection('kids').aggregate([
$group:
_id: null,
maxQuantity: $max: "$age"
])
【讨论】:
The same answer 差不多一年前就已经给出了。 另一个类似的答案似乎不起作用 - 这个语法可以【参考方案5】:伙计们,您可以通过运行计划来了解优化器在做什么。查看计划的通用格式来自 MongoDB documentation。即Cursor.plan()
。如果您真的想深入挖掘,可以通过cursor.plan(true)
获取更多详细信息。
话虽如此,如果您有一个索引,您的 db.col.find().sort("field":-1).limit(1)
将读取一个索引条目 - 即使该索引是默认升序并且您想要最大条目和集合中的一个值。
换句话说,@yogesh 的建议是正确的。
谢谢 - 苏米特
【讨论】:
【参考方案6】:db.collection.findOne().sort(age:-1) //get Max without need for limit(1)
【讨论】:
至少在 Mongo 4.2 中,该语法将为您提供TypeError: db.collection.findOne(...).sort is not a function
。 collection.findOne() 返回文档本身,因此对其调用 sort() 似乎不太可能。【参考方案7】:
简单的解释, 如果您有 mongo 查询响应,如下所示 - 并且您只想要 Array-> "Date"
中的最高值
"_id": "57ee5a708e117c754915a2a2",
"TotalWishs": 3,
"Events": [
"57f805c866bf62f12edb8024"
],
"wish": [
"Cosmic Eldorado Mountain Bikes, 26-inch (Grey/White)",
"Asics Men's Gel-Nimbus 18 Black, Snow and Fiery Red Running Shoes - 10 UK/India (45 EU) (11 US)",
"Suunto Digital Black Dial Unisex Watch - SS018734000"
],
"Date": [
"2017-02-13T00:00:00.000Z",
"2017-03-05T00:00:00.000Z"
],
"UserDetails": [
"createdAt": "2016-09-30T12:28:32.773Z",
"jeenesFriends": [
"57edf8a96ad8f6ff453a384a",
"57ee516c8e117c754915a26b",
"58a1644b6c91d2af783770b0",
"57ef4631b97d81824cf54795"
],
"userImage": "user_profile/Male.png",
"email": "roopak@small-screen.com",
"fullName": "Roopak Kapoor"
],
,
***那么你已经添加了
Latest_Wish_CreatedDate: $max: "$Date",
类似下面的东西-
$project : _id: 1,
TotalWishs : 1 ,
wish:1 ,
Events:1,
Wish_CreatedDate:1,
Latest_Wish_CreatedDate: $max: "$Date",
最终查询响应将在下方
"_id": "57ee5a708e117c754915a2a2",
"TotalWishs": 3,
"Events": [
"57f805c866bf62f12edb8024"
],
"wish": [
"Cosmic Eldorado Mountain Bikes, 26-inch (Grey/White)",
"Asics Men's Gel-Nimbus 18 Black, Snow and Fiery Red Running Shoes - 10 UK/India (45 EU) (11 US)",
"Suunto Digital Black Dial Unisex Watch - SS018734000"
],
"Wish_CreatedDate": [
"2017-03-05T00:00:00.000Z",
"2017-02-13T00:00:00.000Z"
],
"UserDetails": [
"createdAt": "2016-09-30T12:28:32.773Z",
"jeenesFriends": [
"57edf8a96ad8f6ff453a384a",
"57ee516c8e117c754915a26b",
"58a1644b6c91d2af783770b0",
"57ef4631b97d81824cf54795"
],
"userImage": "user_profile/Male.png",
"email": "roopak@small-screen.com",
"fullName": "Roopak Kapoor"
],
"Latest_Wish_CreatedDate": "2017-03-05T00:00:00.000Z"
,
【讨论】:
【参考方案8】:对于最大值,我们可以将sql查询写为
select age from table_name order by age desc limit 1
同样的方式我们也可以在 mongodb 中编写。
db.getCollection('collection_name').find().sort("age" : -1).limit(1); //max age
db.getCollection('collection_name').find().sort("age" : 1).limit(1); //min age
【讨论】:
【参考方案9】:您也可以通过聚合管道来实现。
db.collection.aggregate([$sort:age:-1, $limit:1])
【讨论】:
这有一个糟糕的表现。获得最高价值总是要花费O(n)
没有指标。这有O(n log(n))
的性能@【参考方案10】:
以下查询将为您提供不带其他字段的最大年龄,
db.collection.find(, "_id":0, "age":1).sort(age:-1).limit(1)
以下查询将为您提供最大年龄以及所有集合字段,
db.collection.find().sort(age:-1).limit(1)
【讨论】:
以上是关于mongodb如何从集合中获取最大值的主要内容,如果未能解决你的问题,请参考以下文章