【问题标题】:mongodb how to get max value from collectionsmongodb如何从集合中获取最大值
【发布时间】: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 max


【解决方案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 文档中有提到这一点的地方吗?
【解决方案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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-06
          • 2012-06-10
          • 2016-09-26
          • 1970-01-01
          相关资源
          最近更新 更多