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

Mongoose聚合分组查询如何仅获取每个用户最新的MUTE禁言记录

解决方案

问题根因

你的原查询错误点在$group阶段的分组键设置,使用$sanctions._id作为分组标识会将每条独立的MUTE处罚拆分为独立分组,最终返回所有符合条件的禁言记录,无法实现按用户聚合的效果。

修正后的查询代码

场景1:仅需要返回用户信息 + 最新禁言到期时间

直接通过$max聚合函数取每个用户最大的到期时间即可:

await User.aggregate([
  { $unwind: '$sanctions' },
  { $match: { 'sanctions.type': 'MUTE' } },
  {
    $group: {
      _id: '$_id', // 核心修改:按用户自身的唯一ID分组,确保每个用户对应一条结果
      user: { $first: '$user' },
      expiry: { $max: '$sanctions.expiry' }
    }
  },
  // 可选:调整返回字段格式,和你预期的输出结构对齐
  {
    $project: {
      _id: 1,
      user: 1,
      expiry: 1
    }
  }
]).exec();

场景2:需要返回最新禁言的完整信息(如处罚自身ID等)

如果需要拿到最新到期禁言对应的其他字段,先排序再取每组第一条更稳妥:

await User.aggregate([
  { $unwind: '$sanctions' },
  { $match: { 'sanctions.type': 'MUTE' } },
  // 同用户的处罚按到期时间倒序排列,最新的记录排在最前
  { $sort: { '_id': 1, 'sanctions.expiry': -1 } },
  {
    $group: {
      _id: '$_id',
      user: { $first: '$user' },
      expiry: { $first: '$sanctions.expiry' },
      sanctionId: { $first: '$sanctions._id' } // 按需保留处罚的ID字段
    }
  }
]).exec();

逻辑说明

  • $unwind:将每个用户的sanctions数组展开,单条处罚对应一个独立文档
  • $match:过滤掉非MUTE类型的处罚,降低后续计算开销
  • $group:按用户自身的_id分组,确保每个用户仅返回一条聚合结果
  • $sort:同用户的处罚按到期时间倒序排列后取首条,确保拿到的是最新的禁言记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:45:04