代码之家  ›  专栏  ›  技术社区  ›  Charles R

MongoDB多级组

  •  0
  • Charles R  · 技术社区  · 6 年前

    我有一些输入数据:

    Brand   | Model   | Number
    Peugeot | 208     | 1
    Peugeot | 4008    | 2
    Renault | Clio    | 3
    Renault | Megane  | 4
    

    我想要两个:

    • 每个品牌的总和

    • 全球总和

    以下是我的预期产出:

    Brand   | Number
    Peugeot | 3
    Renault | 7
    Total   | 10
    

    我想我得创造两个 $group 操作和设置总计 $literal . 正确的方法是什么?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Kevin Smith    6 年前

    正如您所说,这可以通过两组by来完成,所以让我们从将一些数据放入mongo开始,类似于您的示例输入:

    > db.cars.insertMany([
       { "Brand" : "Peugeot", "Model" : "208", "Number": 1 },
       { "Brand" : "Peugeot", "Model" : "4008", "Number": 2 },
       { "Brand" : "Renault", "Model" : "Clio", "Number": 3 },
       { "Brand" : "Renault", "Model" : "Megane", "Number": 4 }
     ]);
    

    现在我们已经插入了所有的car,然后可以使用2个group aggregation操作符来聚合它们:

    db.cars.aggregate([
      { $group : { "_id" : "$Brand", "Number" : { $sum : "$Number" }}},
      { $group : { "_id" : null, "Rows" : { $push : { "Brand" : "$$ROOT._id", "Number" : "$Number" } }, "Total" : {$sum : "$Number" } }}
    
    ])
    

    这将为我们提供以下输出

    {
            "_id" : null,
            "Rows" : [
                    {
                            "Brand" : "Renault",
                            "Number" : 7
                    },
                    {
                            "Brand" : "Peugeot",
                            "Number" : 3
                    }
            ],
            "Total" : 10
    }
    

    我们可以用投影来清理

    db.cars.aggregate([
      { "$group" : { "_id" : "$Brand", "Number" : { $sum : "$Number" }}},
      { "$group" : { "_id" : null, "Rows" : { $push : { "Brand" : "$$ROOT._id", "Number" : "$Number" } }, "Total" : {$sum : "$Number" } } },
      { "$project" : { "_id" : 0, "Data" : { "$concatArrays" : [ "$Rows", [ { "Brand": { $literal : "Total" }, "Number" : "$Total" } ] ] } } }
    ])
    

    给我们以下的结果

    {
            "Data" : [
                    {
                            "Brand" : "Renault",
                            "Number" : 7
                    },
                    {
                            "Brand" : "Peugeot",
                            "Number" : 3
                    },
                    {
                            "Brand" : "Total",
                            "Number" : 10
                    }
            ]
    }