具有多个分组依据的MongoDB聚合查询

时间:2020-07-01 11:31:10

标签: mongodb mongodb-query aggregation-framework

希望您可以帮助我是聚合查询的新手。

我想对嵌套的数据结构进行分组以产生统计输出。我有一组订单,其中的订单适用于国家/地区,产品和产品代码。订单如下:

>db.orders.findOne();
{
    "_id" : ObjectId("5efc6db38cb109193e41c4d3"),
    "createdDate" : ISODate("2020-06-25T02:06:25.428Z"),
    "data" : {
        "nested" : {
            "country" : "France"
        },
        "product" : "Product 4",
        "latest" : {
            "sub" : {
                "code" : "Code 3"
            }
        }
    }
}

我有一个汇总查询,按国家,产品和代码分组。

db.getCollection('orders').aggregate([
{
    $unwind :{
        path: "$data.nested.country"
    }
},
{
   $group: {
       _id: { country: "$data.nested.country", product: "$data.product", code: "$data.latest.sub.code" }
   }
}
])

这将产生如下输出:

    { "_id" : { "country" : "Slovenia", "product" : "Product 3", "code" : "Code 7" } }
    { "_id" : { "country" : "Japan", "product" : "Product 1", "code" : "Code 9" } }
    { "_id" : { "country" : "Japan", "product" : "Product 4", "code" : "Code 4" } }
    { "_id" : { "country" : "China", "product" : "Product 1", "code" : "Code 1" } }
    { "_id" : { "country" : "France", "product" : "Product 3", "code" : "Code 4" } }   
    { "_id" : { "country" : "Japan", "product" : "Product 4", "code" : "Code 8" } }
    { "_id" : { "country" : "Japan", "product" : "Product 4", "code" : "Code 5" } }
    { "_id" : { "country" : "Slovenia", "product" : "Product 4", "code" : "Code 4" } }
    { "_id" : { "country" : "Slovenia", "product" : "Product 4", "code" : "Code 7" } }
    { "_id" : { "country" : "Slovenia", "product" : "Product 4", "code" : "Code 2" } }
    { "_id" : { "country" : "China", "product" : "Product 4", "code" : "Code 8" } }
    { "_id" : { "country" : "France", "product" : "Product 4", "code" : "Code 4" } }
    { "_id" : { "country" : "Japan", "product" : "Product 2", "code" : "Code 3" } }
    { "_id" : { "country" : "Japan", "product" : "Product 2", "code" : "Code 6" } }
    { "_id" : { "country" : "Japan", "product" : "Product 2", "code" : "Code 3" } }
    { "_id" : { "country" : "Slovenia", "product" : "Product 2", "code" : "Code 9" } }
    { "_id" : { "country" : "China", "product" : "Product 2", "code" : "Code 6" } }

我想按国家(地区),产品和代码对数据进行分组,例如,日本将有一个产品列表,即Product 4, Product 2,每个产品内部都有一个代码列表,因此"Product 4": ["Code 8","Code 5","Code 3","Code 6","Code 2"]等等。由于可以为一个国家订购具有特定代码的产品多次,因此我需要一个代码图和每个代码的计数。

    { "_id" : { "country": "Japan", products: [{"product":"Product 2","codes":[{"code":"Code 3","count":2},{"code":"Code 6","count":1]}]

1 个答案:

答案 0 :(得分:0)

您处在正确的轨道上。除非您希望data.nested.country是某些订单中的数组,否则您不需要$unwind阶段。

参加小组赛是一个不错的第一步,您只需要添加一个计数器:

{$group: {
    _id: { 
          country: "$data.nested.country", 
          product: "$data.product", 
          code: "$data.latest.sub.code" 
    },
    count: {$sum:1}
}}

这为您提供了不同的国家(地区)+产品+代码,每个都有一个频次计数。 然后按国家和产品分组,将所有代码值及其计数收集到一个数组中:

{$group: {
    _id: { 
          country: "$_id.country", 
          product: "$_id.product" 
    },
    codes:{
           $push: {
                   code:"$_id.code", 
                   count:"$count"
           }
    }
}}

这将使您的每个产品都有一系列带有其计数的代码。 最后,按国家/地区分组,然后将产品收集到一个阵列中:

{$group: {
    _id: { 
          country: "$_id.country" 
    },
    products: { 
          $push:{
                product:"$_id.product", 
                codes: "$codes" 
          },
    }
}}

Playground