mongodb-同一文档的两个依赖聚合
假设提供了以下集合:mongodb-同一文档的两个依赖聚合,mongodb,aggregation-framework,Mongodb,Aggregation Framework,假设提供了以下集合: {"Year" : 2014, "State" : "AZ", "Distributer" : "AAA", "Revenu_category_A" : 300, "Revenu_category_B" : 42, "Revenu_category_C" : 75} {"Year" : 2015,
{"Year" : 2014, "State" : "AZ", "Distributer" : "AAA", "Revenu_category_A" : 300, "Revenu_category_B" : 42, "Revenu_category_C" : 75}
{"Year" : 2015, "State" : "AZ","Distributer" : "AAA","Revenu_category_A" : 475, "Revenu_category_B" : 78, "Revenu_category_C" : 21}
{ "Year" : 2014, "State" : "NY","Distributer" : "AAA","Revenu_category_A" : 74, "Revenu_category_B" : 44, "Revenu_category_C" : 13}
{"Year" : 2015, "State" : "NY","Distributer" : "BBB","Revenu_category_A" : 234, "Revenu_category_B" : 41, "Revenu_category_C" : 433}
对于上述每一个分销商,我想找出贡献最小收入的类别,以及分销商在所有年份中从该类别获得最多收入的州
例如,参考上述数据。如果我们查看分销商AAA
,并计算每个类别的总收入。结果如下:
{"Distributer" : "AAA", "Least_Revenue_category": "Revenu_category_A", "State_with_most_revenue" : "AZ"}
{"Distributer" : "BBB"...}...
A类
的总收入为:849B类
的总收入为:164C类的总收入为:109 根据该结果,
C类
对分销商总收入的贡献最低AAA
(总收入109)
然后我们需要找到类别C
为分销商AAA
产生最多收入的州。该州是亚利桑那州,总收入为96英镑,而纽约州仅为该类收入创造13英镑
因此,预期结果如下所示:
{"Distributer" : "AAA", "Least_Revenue_category": "Revenu_category_A", "State_with_most_revenue" : "AZ"}
{"Distributer" : "BBB"...}...
要使用聚合实现这一点,您需要一种方法来确定哪些字段是收入类别。管道阶段可能是:
- 将收入类别字段收集到键值对数组中
- 展开阵列
- 按经销商、州和类别分组,并计算每个类别的总收入
- 按收入递减排序
- 按经销商和类别分组,存储第一条记录(按州最大值),并计算每个类别的总收入
- 按收入递增排序
- 按分发者分组,捕获每个分发者的第一条记录。这将是该分销商在该类别中的最小类别和最高状态
db.collection.aggregate([
{$addFields: {
fields: {
$filter: {
input: {$objectToArray: "$$ROOT"},
cond: {
"$regexMatch": {
"input": "$$this.k",
"regex": "^Revenu"
}
}
}
}
}},
{$unwind: "$fields"},
{$group: {
_id: {
distributer: "$Distributer",
state: "$State",
category: "$fields.k"
},
stateTotal: {$sum: "$fields.v"}
}},
{$sort: {stateTotal: -1}},
{$group: {
_id: {
distributer: "$_id.distributer",
category: "$_id.category"
},
most: {
$first: {
state: "$_id.state",
stateTotal: "$stateTotal"
}
},
catTotal: {$sum: "$stateTotal"}
}},
{$sort: {catTotal: 1}},
{$group: {
_id: "$_id.distributer",
"Least_Revenue_category": {$first: "$_id.category"},
"State_with_most_revenue": {$first: "$most.state"}
}},
{$project: {
_id: 0,
Distributer: "$_id",
"Least_Revenue_category": 1,
"State_with_most_revenue": 1
}}
])
您能否在问题中添加来自该文档的预期结果。为了使问题更清楚,我对其进行了编辑,并添加了一个具有预期结果的示例。A类到C类字段将是动态的或始终固定的?可以是动态的,但为了简单起见,它可以固定。换句话说,为了简单起见,我们将把这些类别看作三个固定的类别。它非常漂亮,并且给出了解决方案。如果类别是固定的呢?如果不使用正则表达式,解决方案会是什么样子?您所需要的只是
cond
中的一些布尔表达式,对于要视为类别的字段名,该表达式将返回true,而对于其他字段名,该表达式将返回false。这可以是$eq
、$in
、$or
、$not
、$regex
,等等中的任何一个。几乎可以在那里使用任何逻辑查询运算符。