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

如何在MongoDB中查询事件的开始时间、结束时间及状态?

MongoDB 查询事件的开始/结束时间及状态

可以通过MongoDB的聚合框架实现需求,核心是按eventId分组,分别提取对应状态的时间信息。以下是两种常用实现方式:

方法一:分组+条件聚合(兼容所有MongoDB版本)

直接在分组阶段通过条件判断,提取开始和结束时间,还可额外校验事件完整性:

db.yourCollection.aggregate([
  {
    $group: {
      _id: "$eventId",
      // 提取status为started的事件时间
      startTime: {
        $first: {
          $cond: [{ $eq: ["$status", "started"] }, "$eventTime", null]
        }
      },
      // 提取status为ended的事件时间
      endTime: {
        $first: {
          $cond: [{ $eq: ["$status", "ended"] }, "$eventTime", null]
        }
      },
      // 统计该eventId下的开始/结束记录数(用于后续过滤)
      startCount: { $sum: { $cond: [{ $eq: ["$status", "started"] }, 1, 0] } },
      endCount: { $sum: { $cond: [{ $eq: ["$status", "ended"] }, 1, 0] } }
    }
  },
  // 可选:仅保留同时有开始和结束记录的事件
  {
    $match: {
      startCount: { $gt: 0 },
      endCount: { $gt: 0 }
    }
  },
  // 重命名字段并生成事件整体状态
  {
    $project: {
      _id: 0,
      eventId: "$_id",
      startTime: 1,
      endTime: 1,
      status: {
        $cond: [
          { $and: ["$startTime", "$endTime"] },
          "completed",
          "incomplete"
        ]
      }
    }
  }
])

方法二:使用数组转对象简化实现(MongoDB 5.0+)

如果你的MongoDB版本在5.0及以上,可以用$arrayToObject+$replaceRoot实现更简洁的透视效果:

db.yourCollection.aggregate([
  {
    $group: {
      _id: "$eventId",
      // 收集每个状态对应的时间
      eventTimes: { $push: { k: "$status", v: "$eventTime" } }
    }
  },
  // 将状态-时间数组转为对象字段
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          { eventId: "$_id" },
          { $arrayToObject: "$eventTimes" }
        ]
      }
    }
  },
  // 整理字段并生成整体状态
  {
    $project: {
      eventId: 1,
      startTime: "$started",
      endTime: "$ended",
      status: {
        $cond: [
          { $and: ["$started", "$ended"] },
          "completed",
          "incomplete"
        ]
      }
    }
  }
])

注意事项

  1. 替换代码中的yourCollection为你实际的集合名称。
  2. 关于status类型:你描述中提到status是布尔类型,但又说取值为'started'和'ended',这里可能存在笔误。如果实际是布尔类型(比如true代表开始,false代表结束),只需将代码中的"started"替换为true,"ended"替换为false即可。
  3. 若同一eventId存在多条同状态记录,方法一中的$first会取最早的记录,可根据需求换成$last取最晚的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:15:08