MongoDB:根据group by子句选择前N条记录

MongoDB:根据group by子句选择前N条记录,mongodb,aggregation-framework,Mongodb,Aggregation Framework,以下是我收集的样本:- { "_id" : "fffdb22b-912d-4166-909b-7d0fe790ba2a", "companyVendorId" : "1001", "date" : ISODate("2019-01-02T05:30:00.000+05:30"), "amount" : 100 }, { "_id" : "fff94874-27af-4a39-ae59-3a46b8c7f573", "companyVendorId" : "1002", "date

以下是我收集的样本:-

{
"_id" : "fffdb22b-912d-4166-909b-7d0fe790ba2a", 
"companyVendorId" : "1001", 
"date" : ISODate("2019-01-02T05:30:00.000+05:30"),  
"amount" : 100  
},
{
"_id" : "fff94874-27af-4a39-ae59-3a46b8c7f573", 
"companyVendorId" : "1002", 
"date" : ISODate("2019-01-25T05:30:00.000+05:30"),  
"amount" : 200  
 },
{
"_id" : "fff94874-27af-4a39-ae59-3a46b8c7f573", 
"companyVendorId" : "1002", 
"date" : ISODate("2019-01-29T05:30:00.000+05:30"),  
"amount" : 200  
 },

{
"_id" : "fff68faf-2f11-480f-83d2-bfcb45b12d5b", 
"companyVendorId" : "1004", 
"date" : ISODate("2019-01-12T05:30:00.000+05:30"),  
"amount" : 500

 },

{
"_id" : "fff4dfaa-46cd-48e3-a871-1f086a2c5438", 
"companyVendorId" : "1005", 
"date" : ISODate("2019-02-13T05:30:00.000+05:30"),  
"amount" :600

 },

 {
"_id" : "fff18ff2-015e-4ddc-81f2-a12ab3503d05", 
"companyVendorId" : "1006", 
"date" : ISODate("2019-02-08T05:30:00.000+05:30"),  
"amount" : 700

},
{
"_id" : "ffeb16cd-ae1b-4c1e-aa93-d64347b5ff38", 
"companyVendorId" : "1007", 
"date" : ISODate("2019-02-18T05:30:00.000+05:30"),  
"amount" :800
}
要求:-根据金额,我需要每月(本年度)前两名供应商,如果一个月内同一“companyVendorId”有多笔交易,则我们需要显示金额总和

预期结果

{
"month":1
"companyVendorId" : "1004",     
"totalAmount" : 500 
 },
{
 "month":1
"companyVendorId" : "1002",     
"totalAmount" : 400

 },
{
"month":2
"companyVendorId" : "1007",         
"totalAmount" :800
 },

{
"month":2   
"companyVendorId" : "1006",     
"totalAmount" : 700

}
到目前为止,我正在尝试进行查询,以下是我能够进行的查询:-

 db.getCollection('transaction').aggregate([
 {
"$project":
 {
 "amount": 1,
 "companyVendorId":1,

 "month": { "$month": "$date" }, "year": { "$year": "$date" }

 }
 },
 {
 "$match":
   {
    "year": 2020
   }

  }, {
 "$group": {
    "_id": {
    "month": "$month",
   "companyVendorId":"$companyVendorId"
    },
   "totalAmount": { "$sum": "$amount" }
     }
     }
    ])

此查询根据我的要求给出结果,但无法选择前两名供应商。

有点
复杂
。第7阶段和第8阶段是最复杂的部分,因为您需要对具有相同ID的供应商求和。如果top
2…n
供应商相同,我们需要将它们相加,并将其计为供应商
nº1
。供应商的流程相同
Nº2

解释
  • 第一阶段。如果您想应用MongoDB索引,我们可以按
    date
    字段过滤记录。如果没有索引,你可以用我的替换你的两个阶段
  • 第二阶段。我们按
    month
    分组,并创建两个数组,其中包含
    companyVendorId
    amount
  • 第3-4阶段。我们将
    data2
    数组展平,以计算每个
    companyVendorId
    $max
    /
    $min
    金额。这将有助于我们总结具有相同
    companyVendorId
    的顶级供应商
  • 第5-6阶段。现在,我们订购金额最高的供应商,并定义金额最高的供应商列表
  • 第七阶段。在这里,我们确定供应商
    min
    金额。由于
    $group
    取最小值,我们将其替换为下一个供应商
    max
    值:
    {companyVendorId:1,max:500,min:50},---{companyVendorId:1,max:500,min:200},
    {companyVendorId:2,max:400,min:200}-/{companyVendorId:2,max:400,min:200}

  • 第八阶段。现在,我们将具有相同
    companyVendorId
    amount
    且介于
    min
    max
    值之间的供应商相加

  • 第9-10-11阶段。我们将先前的结果展平,转换为所需的输出和排序文档

  • 注意:您需要MongoDB
    v4.2
    。对于早期版本(
    >v3.4
    ),请更换:

    { $replaceWith: "$data3" }
             with 
    { $replaceRoot: {newRoot: "$data3" }}
    

    请包括与输入匹配的预期输出。如果同一个companyVendorId的总和大于top
    companyVendorId
    ,会发生什么情况?示例:
    companyVendorId:“1002”,“totalAmount”:501
    @Valijon所以在本例中companyVendorId:“1002”记录将首先出现。@thammada我不确定您在问什么,我在问题中已经添加的预期输出,以及它与输入的匹配,在预期输出“月”字段显示此记录是哪个月的,并且“companyVendorId”已经在我的集合中,“totalAmount”字段指定“amount”字段的总数。所以我的问题是正确的。@HarishBagora对不起,我错过了那部分。不知怎么的,我可能已经滚动过去了。并认为这是输入。
    { $replaceWith: "$data3" }
             with 
    { $replaceRoot: {newRoot: "$data3" }}