【问题标题】:Find the highest value in MongoDB在 MongoDB 中查找最高值
【发布时间】:2022-01-18 22:43:08
【问题描述】:

我有收藏 - 歌曲

我需要找到最长的歌曲,但歌曲的长度有两种格式:秒和 HH:MM:SS。

{
  "_id": "61179c8d43400f31df195223",
  "name": "song1",
   "time": 2000
},
{
  "_id": "61179c8341f00f31df159223",
  "name": "song2",
  "time": "00:34:16"
},
{
  "_id": "61179c8341f00f31df195223",
  "name": "song3",
  "time": 2800
},
{
  "_id": "61179c8380f00f31df195223",
  "name": "song4",
  "time": "00:01:10"
}
,{
  "_id": "61179c8310f00f31df195223",
  "name": "song5",
  "time": "00:15:10"
}

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    查询

    • 添加一个新字段 timeSec,以秒为单位存储时间
    • 如果时间不是字符串,我们会保留时间(已经是秒)
    • 其他
    • 将字符串拆分为多个部分,例如[1, 2, 10]
    • $zip 部分及其乘数 [[1 3600] [2 60] [10 1]] (1 小时 = 3600 秒等)
    • 在我们多个数组成员之后归约到总和

    *如果它嵌套了很多,你可以使用更多的 tempFields 来取消它的嵌套以提高可读性。

    Test code here

    aggregate(
    [{$set:
      {timeSec:
       {$cond: 
        [{$eq:[{$type:"$time"}, "string"]},
         {$reduce:
          {input:
           {$zip:{inputs:[{$split:["$time", ":"]}, [3600, 60, 1]]}},
           initialValue:0,
           in:
           {$add:
            ["$$value",
             {$multiply:
              [{$toInt:{$arrayElemAt:["$$this", 0]}},
               {$arrayElemAt:["$$this", 1]}]}]}}},
         "$time"]}}},
     {$sort:{timeSec:-1}},
     {$limit:1}])
    

    【讨论】:

      【解决方案2】:

      没有直接的方法可以做到这一点,您可以尝试聚合管道,

      • $addFields 添加或编辑字段
      • $cond 检查是 time 字段编号,使用 $isNumber 如果是,则返回当前 time 否则转到其他部分
      • $let 在使用 $split 拆分后创建内存变量 time 通过“:”
      • $arrayElemAt 获取拆分数组上方的特定元素形式
      • $toInt 将拆分数字转换为整数
      • $multiply 将小时、分钟乘以特定数字,以秒为单位进行转换
      • $sum 获取总秒数
      • $sort time 按降序排列
      • $limit 获取第一个文件
      db.collection.aggregate([
        {
          $addFields: {
            time: {
              $cond: [
                { $isNumber: "$time" },
                "$time",
                {
                  $let: {
                    vars: {
                      time: { $split: ["$time", ":"] }
                    },
                    in: {
                      $sum: [
                        {
                          $multiply: [
                            { $toInt: { $arrayElemAt: ["$$time", 0] } },
                            3600
                          ]
                        },
                        {
                          $multiply: [
                            { $toInt: { $arrayElemAt: ["$$time", 1] } },
                            60
                          ]
                        },
                        { $toInt: { $arrayElemAt: ["$$time", 2] } }
                      ]
                    }
                  }
                }
              ]
            }
          }
        },
        { $sort: { time: -1 } },
        { $limit: 1 }
      ])
      

      Playground

      【讨论】:

        猜你喜欢
        • 2019-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-01
        • 2016-08-09
        相关资源
        最近更新 更多