Javascript 更新所有文档,设置一个值等于从另一个值(MongoDB)获取索引的数组的值

Javascript 更新所有文档,设置一个值等于从另一个值(MongoDB)获取索引的数组的值,javascript,mongodb,shell,Javascript,Mongodb,Shell,我试图在MongoDB中的80k文档集合上执行MongoShell命令 这是一个示例文档: { "weights":[ { "amount":100, "description":"grams", "grams":100 }, { "amount":1, "description":"cup", "grams":258 },

我试图在MongoDB中的80k文档集合上执行MongoShell命令

这是一个示例文档:

{ 
   "weights":[ 
      { 
         "amount":100,
         "description":"grams",
         "grams":100
      },
      { 
         "amount":1,
         "description":"cup",
         "grams":258
      },
      { 
         "amount":1,
         "description":"tbsp",
         "grams":16
      },
      { 
         "amount":1,
         "description":"tsp",
         "grams":5.38
      }
   ],
   "default_units":2,
   "nutrition":{ 
      "calories":598,
      "carbs":22.31,
      "fats":51.36,
      "proteins":22.21,
   },
   "serving_calories":95,
   "serving_carbs":3,
   "serving_fats":8,
   "serving_proteins":2,
}
我想做的是检查集合中的每个文档,并将“服务热量”字段更新为以下内容:

serving_calories = doc.nutrition.calories * (doc.weights[doc.default_units].grams / 100);
因此,正确地执行此操作将使提供的热量=598*(16/100)=‭95.68‬


我找不到正确的命令,无法根据需要从另一个值执行数组索引。什么是要执行的正确mongo命令?

我想我在执行脚本之前没有选择正确的数据库。这是我的剧本:

db.foods.find().forEach(function(doc) {
  db.foods.updateOne({ _id: doc._id },{ $set: { 
    serving_calories: doc.nutrition.calories *  (doc.weights[doc.default_units].grams / 100)
  } } );
});

这可以在MongoDB 4.2及更新版本的原子更新操作中完成。新版本具有更新方法,该方法现在采用文档或,其中可以使用以下阶段:

  • 及其别名
  • 及其别名
  • 还有它的别名
通过以上步骤,您将有三个步骤,即

  • weights
    数组中获取与所示索引对应的文档
    default_units
    字段,并将其设置为要使用的新字段
    service_weight
    在下一个管道中
  • 使用上述计算结果设置
    服务热量
    字段
  • 从阶段1中删除新字段
    service\u weight
  • 您的更新操作如下所示:

    db.foods.update(
        { },
        [
            { "$set": {
                "serving_weight": {
                    "$arrayElemAt": ["$weights", "$default_units"]
                }
            } },
            { "$set": {
                "serving_calories": {
                    "$multiply": [
                        "$nutrition.calories",
                        { "$divide": [ "$serving_weight.grams", 100 ] }
                    ]
                }
            } },
            { "$unset": [ "serving_weight" ] }
        ]
    );
    
    当然,您需要为验证添加逻辑,在不存在元素的情况下,您需要使用并替换适当的值或默认值