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

MongoDB聚合分组获取同类型房间最低价完整文档

嘿,这个需求很常见,我来帮你搞定!你现在的问题是$group只能拿到最低价的数值,但没法直接关联到对应的完整文档——毕竟$first/$last只是取分组后文档的位置,不是按价格排序后的结果。

给你两种实用的方案,按需选择:

方案一:先排序再分组(高效推荐)

核心思路是先把同房间的文档按价格升序排列,这样每个房间组里的第一个文档就是最低价的那个,再用$first直接取完整文档:

db.consolidation.aggregate([
  // 先按房间ID分组排序,再按price.pvp升序,确保同房间最低价文档排在最前面
  { $sort: { "room.id": 1, "price.pvp": 1 } },
  // 按房间ID分组,取每组的第一个文档(也就是该房间最低价的完整文档)
  { 
    $group: {
      _id: "$room.id",
      cheapestDoc: { $first: "$$ROOT" }
    }
  },
  // 将获取到的完整文档替换为根文档,输出格式完全符合你的预期
  { $replaceRoot: { newRoot: "$cheapestDoc" } }
])

方案二:先获取最低价再关联原文档(逻辑更直观)

如果觉得排序的方式不够直观,可以先拿到每个房间的最低价,再通过$lookup关联回原集合,筛选出对应价格的文档:

db.consolidation.aggregate([
  // 第一步:统计每个房间的最低pvp价格
  {
    $group: {
      _id: "$room.id",
      minPvp: { $min: "$price.pvp" }
    }
  },
  // 第二步:关联原集合,匹配房间ID和对应最低价的文档
  {
    $lookup: {
      from: "consolidation",
      let: { roomId: "$_id", targetPvp: "$minPvp" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$room.id", "$$roomId"] },
                { $eq: ["$price.pvp", "$$targetPvp"] }
              ]
            }
          }
        }
      ],
      as: "cheapestDocs"
    }
  },
  // 展开匹配到的文档数组
  { $unwind: "$cheapestDocs" },
  // 替换为根文档,得到最终结果
  { $replaceRoot: { newRoot: "$cheapestDocs" } }
])

两种方案对比

  • 方案一性能更好:只需要一次遍历+排序,适合数据量较大的场景;
  • 方案二逻辑更清晰:分步操作容易理解,但需要额外的关联查询,数据量大时性能略逊。

运行任意一种方案,都能得到你想要的每个房间类型最低价的完整文档啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:55