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

MongoDB聚合查询:获取符合条件的关联随机Status文档

MongoDB聚合查询:获取符合条件的随机Status文档

需求说明

现有三个集合:User、Credit、Status,关联规则为:每个User对应1条Credit数据,对应多条Status数据。需要实现查询:

  • 从Status中随机返回1条文档
  • 满足两个条件:
    1. 该Status的userId不等于当前查询用户的_id
    2. 当前用户的Credit数值 ≥ 该Status的useCredit

集合结构

User集合

[
  {
    "_id": ObjectId("669fbce1704d41e9040cbb41"),
    "Name": "First User"
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb42"),
    "Name": "Second User"
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb43"),
    "Name": "Third User"
  }
]

Credit集合

[
  {
    "_id": ObjectId("669fbce1704d41e9040cbb44"),
    "userId": ObjectId("669fbce1704d41e9040cbb41"),
    "credit": 100
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb45"),
    "userId": ObjectId("669fbce1704d41e9040cbb42"),
    "credit": 10
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb46"),
    "userId": ObjectId("669fbce1704d41e9040cbb43"),
    "credit": 100
  }
]

Status集合

[
  {
    "_id": ObjectId("669fbce1704d41e9040cbb47"),
    "userId": ObjectId("669fbce1704d41e9040cbb41"),
    "status": "First User Status",
    "useCredit": 1
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb48"),
    "userId": ObjectId("669fbce1704d41e9040cbb42"),
    "status": "Second User Status",
    "useCredit": 20
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb49"),
    "userId": ObjectId("669fbce1704d41e9040cbb42"),
    "status": "Second User Status",
    "useCredit": 10
  },
  {
    "_id": ObjectId("669fbce1704d41e9040cbb4a"),
    "userId": ObjectId("669fbce1704d41e9040cbb43"),
    "status": "Third User Status",
    "useCredit": 3
  },
  {
    "_id": ObjectId("669fbdac704d41e9040cbb4c"),
    "userId": ObjectId("669fbce1704d41e9040cbb43"),
    "status": "Third User Status",
    "useCredit": 4
  },
  {
    "_id": ObjectId("669fbdac704d41e9040cbb4d"),
    "userId": ObjectId("669fbce1704d41e9040cbb43"),
    "status": "Third User Status",
    "useCredit": 2
  },
  {
    "_id": ObjectId("669fbdac704d41e9040cbb50"),
    "userId": ObjectId("669fbce1704d41e9040cbb43"),
    "status": "Third User Status",
    "useCredit": 2
  }
]

聚合查询实现

以First User(_id: ObjectId("669fbce1704d41e9040cbb41"))发起查询为例,聚合管道如下:

db.Credit.aggregate([
  // 1. 匹配当前用户的信用记录
  {
    $match: {
      userId: ObjectId("669fbce1704d41e9040cbb41")
    }
  },
  // 2. 关联Status集合,筛选符合条件的记录
  {
    $lookup: {
      from: "Status",
      let: { currentUserId: "$userId", userCredit: "$credit" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $ne: ["$userId", "$$currentUserId"] }, // 排除当前用户自己的Status
                { $lte: ["$useCredit", "$$userCredit"] } // 确保用户信用足够支付该Status的useCredit
              ]
            }
          }
        }
      ],
      as: "validStatuses"
    }
  },
  // 3. 将符合条件的Status数组展开为单个文档
  { $unwind: "$validStatuses" },
  // 4. 随机抽取1条文档
  { $sample: { size: 1 } },
  // 5. 将结果格式化为Status文档的结构
  { $replaceRoot: { newRoot: "$validStatuses" } }
])

代码说明

  1. $match:定位当前用户的信用记录,获取其credit数值和userId。
  2. $lookup:使用子管道关联Status集合,通过$expr引用当前用户的变量,筛选出符合条件的Status文档。
  3. $unwind:把筛选得到的validStatuses数组拆分为独立文档,方便后续随机抽取。
  4. $sample:从符合条件的文档中随机选取1条,实现随机返回的需求。
  5. $replaceRoot:将结果的根节点替换为validStatuses的内容,直接返回标准的Status文档结构。

示例验证

对于First User的查询:

  • 排除自身的Status文档(_id: 669fbce1704d41e9040cbb47)
  • 由于First User信用为100,所有其他Status的useCredit均≤100,因此符合条件的文档为剩余6条,查询会从中随机返回1条。
    (注:原示例中提到排除_id:669fbce1704d41e9040cbb48,该文档useCredit=20,First User信用足够支付,推测是示例描述有误;若为Second User发起查询,其信用为10,才会排除该文档)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:14:54