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

如何结合lookup与aggregate为Recipe文档添加总kcal属性?

解决方法

你已经迈出了很好的一步,实现了总重量的计算!要获取总千卡,我们只需要在聚合管道里多嵌套一层$lookup来关联每个配料对应的营养数据,然后计算每份配料的千卡再求和即可。

完整的聚合代码

const query = Recipe.aggregate([
  // 第一步:关联Ingredients,同时嵌套关联对应的Nutrient
  {
    $lookup: {
      from: 'ingredients', // 对应Ingredient模型的集合名(Mongoose默认小写复数)
      localField: 'ingredients',
      foreignField: '_id',
      as: 'ingredients',
      // 在这个lookup内部,给每个配料关联对应的Nutrient
      pipeline: [
        {
          $lookup: {
            from: 'nutrients', // 对应Nutrient模型的集合名
            localField: 'nutrient',
            foreignField: '_id',
            as: 'nutrient'
          }
        },
        { $unwind: '$nutrient' } // 把nutrient数组展开为单个对象(因为每个配料只关联一个营养项)
      ]
    }
  },
  // 第二步:计算总重量和总千卡
  {
    $addFields: {
      totalWeight: { $sum: '$ingredients.weightInGrams' }, // 保留你原来的总重量计算
      totalKcal: {
        $sum: {
          // 遍历每个配料,计算单份千卡后求和
          $map: {
            input: '$ingredients',
            as: 'ing',
            in: {
              $multiply: [
                { $divide: ['$$ing.nutrient.kcalPerHundredGrams', 100] }, // 每克的千卡值
                '$$ing.weightInGrams' // 配料重量
              ]
            }
          }
        }
      },
      // 可选:给每个配料单独加上计算后的千卡值,方便查看明细
      ingredients: {
        $map: {
          input: '$ingredients',
          as: 'ing',
          in: {
            _id: '$$ing._id',
            weightInGrams: '$$ing.weightInGrams',
            nutrient: '$$ing.nutrient',
            ingredientKcal: {
              $multiply: [
                { $divide: ['$$ing.nutrient.kcalPerHundredGrams', 100] },
                '$$ing.weightInGrams'
              ]
            }
          }
        }
      }
    }
  }
]);

代码解释

  1. 嵌套的$lookup:

    • 外层$lookup先把Recipe关联的所有Ingredient数据拉取进来。
    • 内层的$lookup(放在pipeline里)为每个Ingredient关联对应的Nutrient数据,之后用$unwind把nutrient数组转成单个对象,避免后续计算时处理数组结构。
  2. 总千卡计算:

    • 用$map遍历每个配料,通过公式(每百克千卡 / 100) * 配料重量计算单份配料的千卡。
    • 再用$sum把所有配料的千卡值加总,得到整个食谱的totalKcal。
  3. 可选的配料明细:

    • 如果你需要查看每个配料单独的千卡值,可以用$map给每个Ingredient对象添加ingredientKcal字段,方便调试或返回明细数据。

这样执行聚合后,每个Recipe文档就会带上totalWeight和totalKcal两个汇总属性啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:16:19