mongodb - 如何获得总和的总和拆分,这也是mongoDB中项目的总和

标签 mongodb mongoose mongodb-query aggregation-framework

我有如下类似的mongo文档:

{"client" : "ashwini",
    "data" : [ 
        {
            .....

            "ac" : [ 
                {
                    "cord" : [ 
                        5.0, 
                        0.0
                    ],
                    "power" : 10.0,on:true
                }, 
                {
                    "cord" : [ 
                        52.0, 
                        0.0
                    ],
                    "power" : 22.0,on:true
                }, 
                {
                    "cord" : [ 
                        85.0, 
                        0.0
                    ],
                    "power" : 50.0,on:false
                }, 
                {
                    "cord" : [ 
                        5.0, 
                        50.0
                    ],
                    "power" : 30.0,on:true
                }
            ],
            "fan" : [ 
                {
                    "cord" : [ 
                        10.0, 
                        20.0
                    ],
                    "power" : 50.0,on:true
                }, 
                {
                    "cord" : [ 
                        60.0, 
                        20.0
                    ],
                    "power" : 10.0,on:true
                }, 
                {
                    "cord" : [ 
                        85.0, 
                        20.0
                    ],
                    "power" : 40.0,on:false
                }, 
                {
                    "cord" : [ 
                        10.0, 
                        70.0
                    ],
                    "power" : 10.0,on:true
                }
            ],
            "light" : [ 
                {
                    "cord" : [ 
                        30.0, 
                        0.0
                    ],
                    "power" : 34.0,on:true
                }, 
                {
                    "cord" : [ 
                        66.0, 
                        0.0
                    ],
                    "power" : 10.0,on:true
                }, 
                {
                    "cord" : [ 
                        82.0, 
                        90.0
                    ],
                    "power" : 69.0,on:true
                }, 
                {
                    "cord" : [ 
                        20.0, 
                        50.0
                    ],
                    "power" : 70.0,on:true
                }
            ],
            "name" : "Palm Meadows",
            "floor" : -1.0
        }, 
        ......
    ]
 }

我希望我的查询输出如下:

 {
        agr:{
          lights:10,
          ac:10,
          fan:20
        },
        split:[
          {
            name:"Palm Meadows",
            power:40,
            location:"Mahadevpura",
            lights:10,
            ac:10,
            fan:20
          },
       ....
       ],
}

其中第一个 agr 是打开的客户端“ashwini”的灯/交流/风扇领域中所有功率的总和,并且拆分具有按名称和位置唯一的灯/交流/风扇的单独总和

我的第一次试用如下

db.getCollection('property').aggregate([
                    {$match:{"client":"ashwini"}},
                    {
                        $group:{
                            _id:"$_id",
                            values:{
                                $addToSet:{
                                    name:"$data.name",
                                    floor:"$data.floor",
                                    location:"$data.location",
                                    lights:{$sum:"$data.lights.power"},
                                    fan:{$sum:"$data.fan.power"},
                                    ac:{$sum:"$data.ac.power"}
                                    }
                            }
                        }
                    }
                ])

输出如下

enter image description here

我不确定如何实现我的要求

最佳答案

您可以在 3.4 中使用以下聚合。

第一部分是计算每个位置的总和值。

第二部分是聚合所有位置的总和值。

对于每个 ($map) data 行,$filter 数据文档,其中 on 字段为真接着是 $sum 计算每个请求字段的 power 值(内部 $let)。

外部 $let 表达式计算每个元素的 power 值,它是请求字段的总和以及请求字段值的总和,namelocation 作为 $project 阶段中的 split 字段。

将所有位置的所有请求字段值聚合为 $addFields 阶段中的 aggr 字段,该阶段还保留现有值。

db.getCollection('property').aggregate([
  {"$match":{"client":"ashwini"}},
  {"$project":{
    "_id":0,
    "split":{
      "$map":{
        "input":"$data",
        "as":"d",
        "in":{
          "$let":{
            "vars":{
              "ac":{
                "$sum":{
                  "$let":{
                    "vars":{"acm":{"$filter":{"input":"$$d.ac","as":"ac","cond":"$$ac.on"}}},
                    "in":"$$acm.power"
                  }
                }
              },
              "fan":{
                "$sum":{
                  "$let":{
                    "vars":{"fanm":{"$filter":{"input":"$$d.fan","as":"fan","cond":"$$fan.on"}}},
                    "in":"$$fanm.power"
                  }
                }
              },
              "light":{
                "$sum":{
                  "$let":{
                    "vars":{"lightm":{"$filter":{"input":"$$d.light","as":"light","cond":"$$light.on"}}},
                    "in":"$$lightm.power"
                  }
                }
              }
            },
            "in":{
              "name":"$$d.name",
              "location":"$$d.location",
              "power":{"$sum":["$$ac","$$fan","$$light"]},
              "ac":"$$ac",
              "fan":"$$fan",
              "light":"$$light"
            }
          }
        }
      }
    }
  }},
  {"$addFields":{
    "aggr":{
      "ac":{"$sum":"$split.ac"},
      "fan":{"$sum":"$split.fan"},
      "light":{"$sum":"$split.light"},
      "power":{"$sum":"split.power"}
    }
  }}
])

使用以下查询输出位置和名称的计算值。

$unwind 数据数组后跟关于位置和名称的 $group

$reduce 遍历分组数据,对所有请求的字段值求和。

$group by _id 将数据值推送到数组中以计算所有位置的值。

db.getCollection('property').aggregate([
  {"$unwind":"$data"},
  {"$group":{"_id":{"id":"$_id","name":"$data.name", "location":"$data.location"},"data":{"$push":"$data"}}},
  {"$project":{
    "values":{
      "$reduce":{
        "input":"$data",
        "initialValue":{
              "power":0,
              "ac":0,
              "fan":0,
              "light":0
            },
        "in":{
          "$let":{
            "vars":{
              "ac":{
                "$sum":{
                  "$let":{
                    "vars":{"acm":{"$filter":{"input":"$$this.ac","as":"ac","cond":"$$ac.on"}}},
                    "in":"$$acm.power"
                  }
                }
              },
              "fan":{
                "$sum":{
                  "$let":{
                    "vars":{"fanm":{"$filter":{"input":"$$this.fan","as":"fan","cond":"$$fan.on"}}},
                    "in":"$$fanm.power"
                  }
                }
              },
              "light":{
                "$sum":{
                  "$let":{
                    "vars":{"lightm":{"$filter":{"input":"$$this.light","as":"light","cond":"$$light.on"}}},
                    "in":"$$lightm.power"
                  }
                }
              }
            },
            "in":{
              "power":{"$add":["$$value.power", {"$sum":["$$ac","$$fan","$$light"]}]},
              "ac":{"$add":["$$value.ac", "$$ac"]},
              "fan":{"$add":["$$value.fan", "$$fan"]},
              "light":{"$add":["$$value.light", "$$light"]}
            }
          }
        }
      }
    }
  }},
  {"$group":{"_id":"$_id.id", "split":{"$push":{"name":"$_id.name","location":"$_id.location","values":"$values"}}}},
  {"$addFields":{
    "aggr":{
      "ac":{"$sum":"$split.values.ac"},
      "fan":{"$sum":"$split.values.fan"},
      "light":{"$sum":"$split.values.light"},
      "power":{"$sum":"split.values.power"}
    }
  }}
])

关于mongodb - 如何获得总和的总和拆分,这也是mongoDB中项目的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48979653/

相关文章:

regex - MongoDB 正则表达式未按预期工作

unit-testing - Mocha 测试,before(Each) 没有运行?

arrays - 从 MongoDb 中的数组的数组中删除元素

mongodb - 仅当本地字段存在时才执行条件查找?

javascript - 无法删除 mongodb 条目

node.js - 我如何过滤来自express服务器和nodejs的GET查询

javascript - mongodb -- count() 比 find() 慢多少?

node.js - MongoDB 和 Mongoose 中边界框的数据类型?

database - MongoDB 文本索引搜索

php - MongoDB和PHP简单登录