node.js - 聚合以从文档和数组元素中获取平均值

标签 node.js mongodb mongoose mongodb-query aggregation-framework

我有这些对象的数组:

item1 = {
  name:'item',
  val:1,
  list:[
    {type:'a',value:1},
    {type:'b',value:1},
    {type:'c',value:1}
  ]
};

item2 = {
  name:'item',
  val:5,
  list:[
    {type:'a',value:3},
    {type:'b',value:99},
    {type:'c',value:1}
  ]
};

它们都有相同的数组,相同的类型“a”、“b”和“c”,但值不同。

如何获取类型“a”、“b”和“c”的平均值?

如何获取所有项目的平均值?

期待

itemAvg = {
  name:'item',
  val:3,
  list:[
    {type:'a',value:2},
    {type:'b',value:50},
    {type:'c',value:1}
  ]
};

我想首先按名称和推送列表对 val 进行分组。 然后展开列表。 然后按类型对列表进行分组。

但这行不通

model.aggregate([
{ $match : <condition> },
{ $group : {
  _id:{name:'$name'},
  ValAvg:{$avg:'$val'}
  List:{$push:'list'}
}},
{ $unwind:'$List'},
{ $group:{                
  _id:{type:'$List.type',
  ValueAvg:{$avg:'$List.value'}
}}
])

我希望展开后的最后一组将按曲调类型分组并计算每种不同类型的平均值...但是没有...我得到 ValueAvg=0

谢谢

最佳答案

你需要两个 $unwind阶段,因为您将数组插入数组,然后跟进两个 $group阶段:

model.aggregate([
    { "$match": { <condition> }},
    { "$group": {
        "_id": "name",
        "val": { "$avg": "$val" },
        "list": { "$push": "$list" }
    }},
    { "$unwind": "$list" },
    { "$unwind": "$list" },
    { "$group": {
        "_id": { "name": "$_id", "type": "$list.type" },
        "val": { "$avg": "$val" },
        "valAvg": { "$avg": "$list.value" }
    }},
    { "$sort": { "_id": 1 } },
    { "$group": {
        "_id": "$_id.name",
        "val": { "$avg": "$val" },
        "list": { "$push": {
           "type": "$_id.type",
           "value": "$valAvg"
        }}
    }}
])

所以首先在“类型”级别分组,得到的结果可以得到元素之间的平均值,然后重构原始形式。注意 $sort保留元素的顺序,否则会颠倒:

{
    "_id" : "name",
    "val" : 3,
    "list" : [
            {
                    "type" : "a",
                    "value" : 2
            },
            {
                    "type" : "b",
                    "value" : 50
            },
            {
                    "type" : "c",
                    "value" : 1
            }
    ]
}

如果您想要先$unwind 以避免将数组放在数组中,那么请不要这样做。您在数组外寻找的平均值将受到展开时数组中元素数量的影响。因此,一个文档中包含更多元素的数组到另一个文档中会在确定平均值时更高地“加权”它们的值。

关于node.js - 聚合以从文档和数组元素中获取平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28976643/

相关文章:

javascript - 使用 ".create"时如何使用 Mongoose 添加到数组中的对象

javascript - 使用 Multer - 如何读取上传的文件 (text/.csv)

mongodb - 检查mongo文档字段是否存在

node.js - 关闭数据库时读取 EIO 错误

mongodb - 如何使用 mongo-connector 连接到远程 MongoDB?

node.js - 不嵌套多次用Mongoose查询

node.js - 在 Heroku 的 Express Node 中存储 api key 的位置

node.js - 使用 perf_events 的 nodejs/v8 火焰图中的未知事件

mysql - Node mysql 查询未从查询外部更新变量

Mongodb 与 future 文档的聚合