如何在Gatsby的GraphQL中查询HH:MM:SS格式duration字段最大值及对应id
问题根因
你原有写法无法得到正确结果的核心原因是duration为字符串类型,默认排序走字典序:比如10:00:00的字典序会小于2:00:00(因为首字符1的ASCII码比2小),和实际时长的数值排序逻辑完全不符。
最优解决方法
分不同场景选择对应方案:
场景1:直接处理JSON数组(前端/脚本场景)
写转换函数将duration转为总秒数后再排序:
// 转换HH:MM:SS为总秒数 const parseDuration = (timeStr) => { const [hours, minutes, seconds] = timeStr.split(':').map(Number) return hours * 3600 + minutes * 60 + seconds } // 排序取最长时长的id const maxDurationId = yourJsonArray .sort((a, b) => parseDuration(b.duration) - parseDuration(a.duration))[0].id
场景2:从MongoDB等数据库查询
用聚合管道做字段转换后再排序:
db.collection.aggregate([ // 新增总秒数字段 { $addFields: { durationSec: { $sum: [ { $multiply: [{ $toInt: { $arrayElemAt: [{ $split: ["$duration", ":"] }, 0] } }, 3600] }, { $multiply: [{ $toInt: { $arrayElemAt: [{ $split: ["$duration", ":"] }, 1] } }, 60] }, { $toInt: { $arrayElemAt: [{ $split: ["$duration", ":"] }, 2] } } ] } } }, // 按秒数倒序 { $sort: { durationSec: -1 } }, // 取第一条 { $limit: 1 }, // 只返回需要的id字段 { $project: { id: 1, _id: 0 } } ])
场景3:高频查询场景(长期优化)
数据写入时直接新增duration_sec数值类型字段,存储对应时长的总秒数,后续直接对该字段做排序查询即可,避免每次查询都做字符串切割转换,性能最优。
查询语句可以直接写成你最初的形式,把排序字段替换为duration_sec即可:
( sort: { fields: [duration_sec], order: DESC } limit: 1 )
内容的提问来源于stack exchange,提问作者redstuck
相关产品推荐
相关产品推荐

