【问题标题】:Add up numbers in sub documents将子文档中的数字相加
【发布时间】:2017-04-18 21:06:05
【问题描述】:

我有包含每餐卡路里数的子文档。它们存储为包含食物的对象数组,如下所示:

{
 "_id": ObjectId("58f5fde7eecaaf0317185fd2"),
 "user_id": ObjectId("58d2dd4c8207c28149dbc748"),
 "calories": 2051,
 "date": 20170318,
 "snacks": [
{
  "nutrients": {
    "protein": 3.9,
    "carbs": 58.3,
    "fat": 28.7
  },
  "servings": 20,
  "calories": 426,
  "name": "6 toffee terror whirls"
 }
],
"dinner": [
{
  "nutrients": {
    "protein": "4.2",
    "carbs": "5.5",
    "fat": "27.9"
  },
  "servings": 47.5,
  "calories": 580,
  "name": "Summer Recipe Pesto Sweet pepper, Rocket & Mozarella"
  }
],
 "lunch": [
{
  "nutrients": {
    "protein": 11.3,
    "carbs": 27.3,
    "fat": 8.1
  },
  "servings": 75,
  "calories": 730,
  "name": "Wood fired rostello ham, chestnut mushrooms & mascarpone 12'' pizza"
}
],
"breakfast": [
{
  "nutrients": {
    "protein": 12.6,
    "carbs": 0.1,
    "fat": "9"
  },
  "servings": "20",
  "calories": 110,
  "name": "15 eggs from caged hends - class A"
},
{
  "nutrients": {
    "protein": "31",
    "carbs": 0.1,
    "fat": "15"
  },
  "servings": "15",
  "calories": 164,
  "name": "Smoked thick cut bacon"
}
]
}

我想要做的是将单个用户添加的一天的总卡路里相加,因此将每个食物对象的卡路里量相加。我知道我需要将聚合方法与 $group 和 $sum 一起使用,但是我不确定如何正确使用它。任何帮助将不胜感激。

我需要的是输入的每天的总卡路里。 例如

20170318 : 2018 , 20170230 : 1990

等等等等

这是我尝试过的,但目前无法正常工作:

        user_food.find({username: req.body.username},{$group:{_id:{date:{$dayOfYear: "$date"}},total:{$sum:'$calories'}}}, function (err, user) {
        //if the user exists
        if (err) {
            console.log("something went wrong: " + err);
            return res.status(500).send(err);
        } else {
            return res.status(200).send(user);
        }
    });

【问题讨论】:

    标签: javascript mongodb mongoose


    【解决方案1】:

    您可以使用$reduce 运算符为每餐使用$add

    db.collection.aggregate(
        {$match:{user_id:ObjectId("58d2dd4c8207c28149dbc748")}},
        {
          $project: {
            date:1,
            calories: { $add: [ {
              $reduce: {
                input: "$breakfast",
                initialValue: 0,
                in: { $add : ["$$value", "$$this.calories"] }
              }
            }, {
              $reduce: {
                input: "$lunch",
                initialValue: 0,
                in: { $add : ["$$value", "$$this.calories"] }
              }
            },{
              $reduce: {
                input: "$snacks",
                initialValue: 0,
                in: { $add : ["$$value", "$$this.calories"] }
              }
            }, {
              $reduce: {
                input: "$dinner",
                initialValue: 0,
                in: { $add : ["$$value", "$$this.calories"] }
              }
            } ] }
          }
        }
    )   
    

    【讨论】:

    • 这行得通,给了我正确的细节。我将如何添加到查询中以获得特定于单个用户的结果?
    • 您对单个用户的查询是什么? _id 还是 user_id? {$match:{user_id:ObjectId("58d2dd4c8207c28149dbc748")}} 之前的 $project 阶段。
    • 使用 match 将响应更改为空数组。我知道用户有条目,所以我不太确定问题是什么。抱歉问了这么多问题,我对 mongodb 很陌生
    • 完全没问题。乐意效劳。你能告诉我你的匹配过滤器吗?更新了答案以包含用于比较的匹配过滤器
    • 会话被赋予 users_id user_food.aggregate({ $match: { user_id: req.session.user_id } }, { $project: {... your method
    【解决方案2】:

    在按日期分组和总卡路里之前使用 $unwind,

       db.collection.aggregate([{
          $match: {
              key: value
          }
       }, {
          $unwind: "$snacks"
       }, {
          $group: {
              _id: "$date",
              totalCalories: {
                  $sum: "$calories"
              }
          }
       }])
    

    第 20170318 天的输出将是,

    { "_id" : 20170318, "totalCalories" : 2051 }
    

    【讨论】:

    • 当我尝试这个时,我得到一个空数组的响应
    • 检查我将匹配条件作为 key:value ,根据您的要求进行更改,或删除匹配段
    猜你喜欢
    • 2014-07-29
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2019-01-04
    • 2015-08-19
    • 2022-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多