Arrays MongoDB:使用2个嵌套数组更新文档中的平均值

Arrays MongoDB:使用2个嵌套数组更新文档中的平均值,arrays,mongodb,mongodb-query,Arrays,Mongodb,Mongodb Query,我有以下MongoDB文档: { _id:ObjectId(), 公司名称:“名称”, 注册日期:2015年2月21日2:00, 卡车:[ { 卡车识别号:“TEB7622”, 体重:88.33, 容量:273.333, 长度:378.333, 宽度:377.383, 平均等级:2.5, 等级:[ { 等级编号:4, 时间戳:2015年2月21日2:00 } ] }, { 卡车识别号:“TEB5572”, 重量:854.33, 容量:2735.333, 长度:378.333, 宽度:37.383

我有以下MongoDB文档:

{
_id:ObjectId(),
公司名称:“名称”,
注册日期:2015年2月21日2:00,
卡车:[
{
卡车识别号:“TEB7622”,
体重:88.33,
容量:273.333,
长度:378.333,
宽度:377.383,
平均等级:2.5,
等级:[
{
等级编号:4,
时间戳:2015年2月21日2:00
}
]
},
{
卡车识别号:“TEB5572”,
重量:854.33,
容量:2735.333,
长度:378.333,
宽度:37.383,
平均成绩:3.8,
等级:[
{
等级编号:4,
时间戳:2015年2月21日2:00
}
]
}
]
}
我想通过添加所有
等级号来更新每辆卡车的
平均等级
。我遇到的问题是,我试图添加的
grade\u编号
位于一个数组中的一个数组中。我尝试使用
$unwind
来展开卡车和坡度阵列

这是我尝试使用的查询:

db.col.aggregate([
{$REWIND:“$TRUMPS”},
{$REWIND:“$TRUMKS.grades”},
{$project:{
“\u id”:“$trucks.truck\u id”,
“卡车.平均等级”:{$avg:{$sum:“卡车.等级.等级编号”}
} 
}])

我需要在我的查询中添加更多内容吗?我想更新所有的
卡车。平均等级
,因为我试图更新的文档中有很多等级。

您不能使用
聚合
来更新文档,但您肯定可以使用它来获取要用于更新的数据。首先,我注意到
grade
数组中的
grade
对象周围缺少一些
{}
。您可能需要再次检查文档结构是否已过帐。其次,聚合查询有几个问题

  • $avg
    操作符在
    $group
    子句中工作,而不是在
    $project
    中工作
  • 使用
    $avg
    时,不需要使用
    $sum
  • 您需要平均
    卡车.grades.grade.grade\u编号
    ,该编号实际上包含坡度的数值。也就是说,在
    等级
    等级编号
    之间缺少
    等级
  • 如果您解决了这些问题,您将得到类似于以下内容的查询:

    db.col.aggregate([
    {“$REWIND”:“$TRUMKS”},
    {“$REWIND”:“$TRUMKS.grades”},
    {“$组”:
    { 
    “\u id”:“$trucks.truck\u id”,
    “平均等级”:{“$avg”:“$trucks.grades.grades_number”}
    } 
    }
    ]);
    
    对于示例文档,返回:

    {u id:“TEB5572”,“平均成绩”:4}
    {“_id”:“TEB7622”,“平均成绩”:4}
    
    现在,您可以使用此信息更新
    average\u grade
    字段。如果您使用的是MongoDB 2.6版或更高版本,则
    aggregate
    方法将返回光标。您可以遍历该游标并相应地更新文档

    在本例中,我在其
    trucks
    数组中搜索具有特定
    truck\u id
    的文档,并继续使用聚合查询计算的
    average\u grade
    更新
    。您可以修改它以满足您的需要。结合聚合查询,代码如下所示

    //获取每辆卡车的平均坡度,并将结果分配给游标。
    var cur=db.col.aggregate([
    {“$REWIND”:“$TRUMKS”},
    {“$REWIND”:“$TRUMKS.grades”},
    {“$组”:
    { 
    “\u id”:“$trucks.truck\u id”,
    “平均等级”:{“$avg”:“$trucks.grades.grades_number”}
    } 
    }
    ]);
    //迭代结果并更新每辆卡车的平均坡度。
    while(cur.hasNext()){
    var doc=cur.next();
    db.col.update({“trucks.truck_id”:doc._id},
    {“$set”:{“trucks.$.average_grade”:doc.average_grade},
    {“多”:真});
    }
    
    您不能使用聚合来更新document@Michael9那么我需要运行两个查询,对吗?一个获取平均值,一个更新平均值?我是否必须将平均值存储在另一个“变量”上?如果需要查询其中的数据,则双嵌套数组不是一个好主意。如果数据仅用于显示,则它们是正常的。也许您应该重新考虑数据模型?也许每辆卡车都应该是自己的文档,带有
    公司id
    字段?还是每个等级都有自己的文件?您不想依靠双重展开聚合管道进行常规查询,因此我不建议使用以下解决方案,除非查询不常见。@wdberkeley这不会让它有点像关系数据库吗?我是MongoDB的新手,所以这是我第一次实际建模文档数据库。我只是多次使用这个查询(实际的计算将在Hadoop中进行)。是的,就是这样。谢谢。