You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB如何按15分钟时间间隔分组统计各时段在线用户

可以仅使用MongoDB原生聚合能力实现该需求,不需要引入自定义JavaScript脚本,核心思路是先计算每个用户连接时段覆盖的所有15分钟时间槽,再展开后分组统计。


完整聚合语句

collection.aggregate([
  // 1. 计算每个会话的起始时间槽、结束时间槽
  {
    $addFields: {
      slotStep: 1000 * 60 * 15, // 15分钟对应的毫秒数
      startSlot: {
        $toDate: {
          $subtract: [
            { $toLong: "$connection" },
            { $mod: [{ $toLong: "$connection" }, 1000 * 60 * 15] }
          ]
        }
      },
      endSlot: {
        $toDate: {
          $subtract: [
            { $toLong: "$disconnection" },
            { $mod: [{ $toLong: "$disconnection" }, 1000 * 60 * 15] }
          ]
        }
      }
    }
  },
  // 2. 生成该会话覆盖的所有时间槽数组
  {
    $addFields: {
      // 计算覆盖的槽位总数,+1是因为首尾槽都需要计入
      slotCount: {
        $add: [
          {
            $divide: [
              { $subtract: ["$endSlot", "$startSlot"] },
              "$slotStep"
            ]
          },
          1
        ]
      }
    }
  },
  {
    $addFields: {
      timeSlots: {
        $map: {
          // 生成从0到slotCount-1的偏移序列
          input: { $range: [0, "$slotCount"] },
          as: "offset",
          in: {
            $add: ["$startSlot", { $multiply: ["$$offset", "$slotStep"] }]
          }
        }
      }
    }
  },
  // 3. 把每个时间槽拆成独立文档
  { $unwind: "$timeSlots" },
  // 4. 按时间槽分组统计
  {
    $group: {
      _id: "$timeSlots",
      count: { $sum: 1 },
      users: { $addToSet: "$user" }
    }
  },
  // 按时间正序排序
  { $sort: { _id: 1 } }
])

关键逻辑说明

  • 槽位对齐计算:对每个会话的连接、断开时间都做15分钟向下取整,得到该会话覆盖的第一个和最后一个时间槽
  • 多槽位生成:通过$range生成偏移序列,批量转换为所有覆盖的时间槽,解决跨时段统计问题
  • 展开后分组:$unwind将每个时间槽拆分为独立文档后,再按时间槽分组即可得到每个时段的所有在线用户

内容的提问来源于stack exchange,提问作者Laubuur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:45:05