代码之家  ›  专栏  ›  技术社区  ›  Andrey Yaskulsky

为表示数组的字段计算组中的平均值

  •  0
  • Andrey Yaskulsky  · 技术社区  · 6 年前

    我有以下文件:

    {
    "name":"St Peterburg",
    "checkInAt" : ISODate(...),
    "areas": [
            {"length":2.0; "width":3.0}, 
            {"length":4.0; "width":3.0}, 
            {"length":2.0; "width":1.0}
           ]
    
    }
    

    我需要一个查询,该查询将按天对这些文档进行分组,并为每个组计算一个小数点,该小数点等于组中所有区域数组的平均值(长度*宽度)。因此,如果在一组中,我有两个文档:

    A { areas:[{"length":2; "width":3}; {"length":3; "width":4};], 
    B { areas:[{"length":4; "width":5}; {"length":5; "width":6};]
    

    我需要计算一下 X = avg(2*3;3*4;4*5;5*6) ;

    到目前为止,我的查询如下所示:

    db.getCollection('areas').aggregate([
            {
                "$group": {
                    "_id": {
                        "$dateToString": {
                            "format": "%Y-%m-%d",
                            "date": "$checkInAt"
                        }
                    },
    
                    "avgArea": {$avg: {"$multiply":["$$areas.length","$$areas.width"]}}
                }
            }
        ])
    

    但这行不通,

    如果能给我一些提示,我会非常感激的

    2 回复  |  直到 6 年前
        1
  •  1
  •   dnickless    6 年前

    这应该可以让你继续:

    db.getCollection('areas').aggregate([{
        $unwind: "$areas" // flatten the "areas" array into multiple documents
    }, {
        $group: {
            "_id": "$checkInAt", // group everything by "checkInAt"
            "avgArea": { $avg: { $multiply: [ "$areas.length", "$areas.width" ] } } // calculate the average
        }
    }])
    
        2
  •  1
  •   s7vr    6 年前

    您可以尝试以下聚合。

    db.getCollection('areas').aggregate(
    [{"$unwind":"$areas"},
     {"$group":{
      "_id":{
        "$dateToString":{"format":"%Y-%m-%d","date":"$checkInAt"}
      },
      "avgArea":{
        "$avg":{"$multiply":["$areas.length","$areas.width"]}
      }
    }}])
    

    您还可以计算平均值,无需 $unwind . 计算 $sum 在所有数组中,首先通过计算 $总和 对于每个数组,后跟每个组的所有数组。

    将数组计数保留在单独的字段中。

    $project 将总和除以计数得到平均值。

    db.getCollection('areas').aggregate(
    [{"$group":{
      "_id":{
          "$dateToString":{"format":"%Y-%m-%d","date":"$checkInAt"}
       },
      "sumArea":{
        "$sum":{
          "$sum":{
            "$map":{
              "input":"$areas",
              "as":"val",
              "in":{"$multiply":["$$val.length","$$val.width"]}
            }
          }
        }
      },
      "countArea":{"$sum":{"$size":"$areas"}}
    }},
    {"$project":{
      "avgArea":{"$divide":["$sumArea","$countArea"]}
    }}])