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的供应商求和。如果top2…n
供应商相同,我们需要将它们相加,并将其计为供应商nº1
。供应商的流程相同Nº2
解释
date
字段过滤记录。如果没有索引,你可以用我的替换你的两个阶段month
分组,并创建两个数组,其中包含companyVendorId
和amount
值李>
data2
数组展平,以计算每个companyVendorId
的$max
/$min
金额。这将有助于我们总结具有相同companyVendorId
的顶级供应商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
值之间的供应商相加注意:您需要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" }}