Mongodb:聚合查询返回当月表现最佳的5个

时间:2019-02-20 09:34:14

标签: mongodb mongoose

我需要每个月销量最高的前5名客户。

这是我收藏的一些json示例

[ {
        "_id" : ObjectId("5c6cf92bd95bb300159ccde5"),
        "userId" :ObjectId("12332xxxxxxxxxxxxxxx"),
        "sale":555,
        "createdAt" : ISODate("2019-02-20T11:52:27.244+05:00")
       },
     {
        "_id" : ObjectId("5c6cf92bd95bb300159ccde5"),
        "userId" :ObjectId("123ww2xxxxxxxxxxxxxxx"),
        "sale":600,
        "createdAt" : ISODate("2019-03-20T11:52:27.244+05:00")
       }]

这是我正在尝试的查询

[
      {
        $group: {
          _id: { 
            $month: "$createdAt",
          },
          sales: {$sum:"$sale"}.
          customer:{$first:"$customer"},
          numberofSales: { $sum: 1 }
        }
      },
      { $sort: { _id: 1 } }
    ]

它只返回一个月的客户,我需要每个月的前五名客户

1 个答案:

答案 0 :(得分:0)

我什至不相信通过明确的请求就可以得到想要的东西,但是在这里

db.getCollection('stack54783009').aggregate([
      {
        $group: {
          _id: { 
            month:{$month: "$createdAt"},
            year:{$year: "$createdAt"},
            user:"$userId"
          },
          sales: {$sum:"$sale"},
          customer:{$first:"$customer"},
          numberofSales: { $sum: 1 }
        }
      },
      { $sort: { "_id.year": 1,"_id.month": 1,sales:-1 } },    
      { $group : { _id : {m:"$_id.month",y:"$_id.year"}, data: { $push: {sales:"$sales",numberofSales:"$numberofSales",userId:"$_id.user",customer:"$customer"} } } },
      { $unwind: { path: "$data", includeArrayIndex: "order" } },
      { $match: {order:{$lte:4}}},
      { $project:{
            _id: 0,
            m:"$_id.m",
            y:"$_id.y",
            user:"$data.userId",
            numberofSales:"$data.numberofSales",
            customer: "$data.customer",
            sales:"$data.sales"
      }},
      { $sort: {y:1,m:1,sales:-1}}
])

您应该正确地对文档进行分组

...
$group: {
  _id: { 
    month:{$month: "$createdAt"},
    year:{$year: "$createdAt"},
    user:"$userId"
  },
... 

然后排序,将数据推送到数组中,使用数组索引展开,限制5个元素(或更少)并获取普通文档。

结果:

/* 1 */
{
    "m" : 2,
    "y" : 2019,
    "user" : 2.0,
    "numberofSales" : 1.0,
    "sales" : 600.0
}

/* 2 */
{
    "m" : 2,
    "y" : 2019,
    "user" : 1.0,
    "numberofSales" : 1.0,
    "sales" : 555.0
}

/* 3 */
{
    "m" : 2,
    "y" : 2019,
    "user" : 7.0,
    "numberofSales" : 1.0,
    "sales" : 90.0
}

/* 4 */
{
    "m" : 3,
    "y" : 2019,
    "user" : 2.0,
    "numberofSales" : 4.0,
    "sales" : 1900.0
}

/* 5 */
{
    "m" : 3,
    "y" : 2019,
    "user" : 3.0,
    "numberofSales" : 1.0,
    "sales" : 1600.0
}

/* 6 */
{
    "m" : 3,
    "y" : 2019,
    "user" : 5.0,
    "numberofSales" : 2.0,
    "sales" : 860.0
}

/* 7 */
{
    "m" : 3,
    "y" : 2019,
    "user" : 6.0,
    "numberofSales" : 2.0,
    "sales" : 600.0
}

/* 8 */
{
    "m" : 3,
    "y" : 2019,
    "user" : 4.0,
    "numberofSales" : 2.0,
    "sales" : 120.0
}

但是您可以简化查询执行:

db.getCollection('stack54783009').aggregate([
      {
        $group: {
          _id: { 
            month:{$month: "$createdAt"},
            year:{$year: "$createdAt"},
            user:"$userId"
          },
          sales: {$sum:"$sale"},
          customer:{$first:"$customer"},
          numberofSales: { $sum: 1 }
        }
      },
      { $sort: { "_id.year": 1,"_id.month": 1,sales:-1 } },    
])

并在客户端处理结果。