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

使用MongoDB聚合框架转换对象并计算字段值差值的实现问题

方案说明

首先需要纠正你预期结果的格式问题:JSON 规范不允许单个对象内存在重复的键,你给出的预期结果里每个对象同时存在两个name和两个data字段,实际无法正常存储和使用,因此下面的方案会将两个配对的原始对象分别存入itemA和itemB字段,避免键冲突。

聚合查询代码

// 你可以直接把这个管道传给mongoose的Model.aggregate()方法使用
const aggregationPipeline = [
  // 收集集合内所有文档到同一个数组
  {
    $group: {
      _id: null,
      allItems: { $push: "$$ROOT" }
    }
  },
  // 生成所有两两有序配对,同时计算价格差值
  {
    $project: {
      pairs: {
        $reduce: {
          input: "$allItems",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              {
                $map: {
                  input: {
                    // 过滤掉自身和自身配对的情况
                    $filter: {
                      input: "$allItems",
                      cond: { $ne: ["$$this._id", "$$item._id"] }
                    }
                  },
                  as: "secondItem",
                  in: {
                    itemA: "$$item",
                    itemB: "$$secondItem",
                    // 差值 = 第一个商品价格 - 第二个商品价格
                    difference: { $subtract: ["$$item.data.price.last", "$$secondItem.data.price.last"] }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  // 将配对数组拆分为独立文档
  { $unwind: "$pairs" },
  // 调整输出结构,将配对对象作为根文档返回
  {
    $replaceRoot: { newRoot: "$pairs" }
  }
];

可选过滤步骤

如果你只需要你示例中列出的4种特定配对,可以在上述管道的最后新增一个$match阶段过滤结果:

{
  $match: {
    $or: [
      { "itemA.name": "Helicopter", "itemB.name": "Car" },
      { "itemA.name": "Car", "itemB.name": "Truck" },
      { "itemA.name": "Truck", "itemB.name": "Helicopter" },
      { "itemA.name": "Car", "itemB.name": "Helicopter" }
    ]
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:06:04