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

Mongoose如何统计最新会话国家为USA的用户数量

问题背景

现有Mongoose用户表Schema定义如下:

const userSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    sessions: [{
        token: {
            type: String,
            required: true
        },
        agent: {
            ip: {
                type: String,
                required: true
            },
            country: {
                type: String,
                required: true
            },
        },
        update: {
            type: Date,
            default: Date.now
        },
    }]
})

需求为:提取每个用户sessions数组中update字段值最大(最新)的会话,统计该最新会话agent.country值为usa的用户总数量。
原有错误实现代码如下:

let count = await User.countDocuments({ 'sessions.agent.country': 'usa' })
console.log('count: ' + count)

该逻辑的问题是:countDocuments的匹配规则会遍历sessions数组的所有元素,只要用户任意一条历史会话的country为usa就会被统计,完全没有校验该会话是否为用户最新会话,统计结果会偏大。

正确实现代码

使用MongoDB聚合管道实现,无需拆分数组,性能更优:

const countResult = await User.aggregate([
  // 为每个用户提取最新的会话记录
  {
    $addFields: {
      latestSession: {
        $reduce: {
          input: "$sessions",
          initialValue: { update: new Date(0) },
          in: {
            $cond: [
              { $gt: ["$$this.update", "$$value.update"] },
              "$$this",
              "$$value"
            ]
          }
        }
      }
    }
  },
  // 仅匹配最新会话国家为usa的用户
  {
    $match: {
      "latestSession.agent.country": "usa"
    }
  },
  // 统计符合条件的总用户数
  {
    $count: "total"
  }
])

// 无匹配结果时聚合返回空数组,总数默认取0
const count = countResult[0]?.total || 0
console.log('count: ' + count)
逻辑说明
  • 用$reduce遍历单用户的所有sessions记录,逐次对比update时间,始终保留时间更大的会话,最终得到该用户的最新会话,该操作不需要拆分数组,相比$unwind实现性能更高,兼容MongoDB 4.0及以上版本
  • 匹配阶段仅针对提取出的最新会话做国家字段校验,不会命中历史旧会话数据
  • 最终通过$count直接返回符合条件的用户总数,结果完全匹配需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:57:19