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

如何在MongoDB中筛选含active和renew状态的用户并去重数组元素

MongoDB 筛选同时拥有指定状态的用户并对数组去重

问题说明

需要筛选出Keys数组中同时包含keyStatus为active和renew的用户,并且返回结果时对Keys数组按keyType+keyStatus组合去重,去除重复条目。

注意:原过滤器{keys: {$elemMatch: {status: {$in: ["active", "renew"] }}}}仅能匹配数组中存在任意一种状态的用户,无法确保同时拥有两种状态,需先修正筛选条件。

解决方案:使用聚合管道实现筛选+去重

方法一:内存中直接处理数组去重(适合数组元素较少的场景)

通过$match筛选符合条件的用户,再用$reduce对Keys数组去重:

db.users.aggregate([
  // 筛选同时拥有active和renew状态的用户
  {
    $match: {
      $and: [
        {"Keys.keyStatus": "active"},
        {"Keys.keyStatus": "renew"}
      ]
    }
  },
  // 对Keys数组按keyType+keyStatus组合去重
  {
    $addFields: {
      Keys: {
        $reduce: {
          input: "$Keys",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              {
                $cond: [
                  {
                    $not: {
                      $in: [
                        {keyType: "$$this.keyType", keyStatus: "$$this.keyStatus"},
                        "$$value"
                      ]
                    }
                  },
                  ["$$this"],
                  []
                ]
              }
            ]
          }
        }
      }
    }
  }
])

方法二:通过展开+分组实现去重(适合数组元素较多的场景)

利用$unwind展开数组,再通过两次$group分别去重和重组数组:

db.users.aggregate([
  // 筛选同时拥有active和renew状态的用户
  {
    $match: {
      $and: [
        {"Keys.keyStatus": "active"},
        {"Keys.keyStatus": "renew"}
      ]
    }
  },
  // 展开Keys数组
  { $unwind: "$Keys" },
  // 按用户ID+keyType+keyStatus分组,去除重复条目
  {
    $group: {
      _id: {
        userId: "$_id",
        keyType: "$Keys.keyType",
        keyStatus: "$Keys.keyStatus"
      },
      // 保留用户其他字段,示例为name,可根据实际需求添加
      name: { $first: "$name" },
      keyInfo: { $first: "$Keys" }
    }
  },
  // 按用户ID重新分组,聚合去重后的Keys数组
  {
    $group: {
      _id: "$_id.userId",
      name: { $first: "$name" },
      Keys: { $push: "$keyInfo" }
    }
  }
])

说明

  • 两种方法都会先筛选出同时拥有active和renew状态的用户,再对Keys数组去重;
  • 方法一无需展开数组,内存处理更快,但数组过大时可能性能下降;
  • 方法二通过分组去重,适合大数据量场景,但需要处理用户其他字段的保留逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:41:18