计算 MongoDB 中对象值的平均值
Calculate average for object values in MongoDB
我想根据 2021 年的平均评分对这些记录进行降序排序:
[
{
"id": 1,
"slug": "shop 1",
"stats": {
"time_stats": {
"2021": {
"1": 9.04,
"2": 8.17,
"10": 8.46,
"7": 9.35,
"11": 8.53,
"6": 8.35,
"5": 8.63,
"9": 9.13,
"3": 8.9,
"8": 7.64,
"4": 8.65,
"12": 7.45
},
}
}
},
{
"id": 2,
"slug": "shop 2",
"stats": {
"time_stats": {
"2021": {
"1": 5,
"10": 9.35,
"12": 6,
"11": 8,
"2": 3,
"3": 5,
"9": 4
},
}
}
},
{
"id": 3,
"slug": "shop 3",
"stats": {
"time_stats": {
"2021": {
"3": 9.57,
"11": 7.83,
"4": 8.94,
"2": 9.1,
"6": 8.5,
"5": 9.43,
"12": 7.93,
"10": 9.28,
"9": 9.84,
"7": 9.38,
"1": 8.91,
"8": 9.75
},
}
}
}
]
2021 对象中的每个属性代表一个月。我不知道从哪里开始,Here's what I've tried 到目前为止
db.collection.aggregate([
{
$unwind: "$stats"
},
{
$unwind: "$stats.time_stats.2021"
},
{
$group: {
_id: "$slug",
yearAvg: {
$avg: {
$sum: [
"$stats.time_stats.2021.1",
"$stats.time_stats.2021.2",
"$stats.time_stats.2021.3",
"$stats.time_stats.2021.4",
"$stats.time_stats.2021.5",
"$stats.time_stats.2021.6",
"$stats.time_stats.2021.7",
"$stats.time_stats.2021.8",
"$stats.time_stats.2021.9",
"$stats.time_stats.2021.10",
"$stats.time_stats.2021.11",
"$stats.time_stats.2021.12",
]
}
}
}
}
])
但我不确定如何继续实施。非常感谢任何帮助!
首先,您需要一种将 time_stats
散列转换为数组的方法,这将帮助您推导平均值,因为 MongoDB 已经有有用的运算符,例如$avg
. The $avg
运算符
在数组操作数上工作以 return 平均值。在你的情况下,你需要一个转换 hashmap
的操作
{
"1": 9.04,
"2": 8.17,
"10": 8.46,
"7": 9.35,
"11": 8.53,
"6": 8.35,
"5": 8.63,
"9": 9.13,
"3": 8.9,
"8": 7.64,
"4": 8.65,
"12": 7.45
}
使用 $objectToArray
运算符到键值对象数组,让我们调用新字段 time_stats_2001_average
:
{
time_stats_2001_average: [
{ "k" : "1", "v" : 9.04 },
{ "k" : "2", "v" : 8.17 },
{ "k" : "3", "v" : 8.9 },
{ "k" : "4", "v" : 8.65 },
{ "k" : "5", "v" : 8.63 },
{ "k" : "6", "v" : 8.35 },
{ "k" : "7", "v" : 9.35 },
{ "k" : "8", "v" : 7.64 },
{ "k" : "9", "v" : 9.13 },
{ "k" : "10", "v" : 8.46 },
{ "k" : "11", "v" : 8.53 },
{ "k" : "12", "v" : 7.45 }
]
}
然后使用表达式计算平均值:
{ time_stats_2001_average: { $avg: '$time_stats_2001_average.v' } }
使用排序运算符在新字段上对生成的文档进行排序:
{ $sort : { time_stats_2001_average : -1 } }
您的完整聚合管道如下所示 (Mongo Playground):
db.collection.aggregate([
{ '$addFields': {
'time_stats_2001_average': {
'$avg': {
'$map': {
'input': {
'$objectToArray': '$stats.time_stats.2021'
},
'in': '$$this.v'
}
}
}
} },
{ '$sort': { 'time_stats_2001_average': -1 } }
])
使用另一个替代管道 (Mongo Playground):
db.collection.aggregate([
{ '$addFields': {
'time_stats_2001_average': {
'$objectToArray': '$stats.time_stats.2021'
}
} },
{ '$addFields': {
'time_stats_2001_average': {
'$avg': '$time_stats_2001_average.v'
}
} },
{ '$sort' : { 'time_stats_2001_average' : -1 } }
])
我想根据 2021 年的平均评分对这些记录进行降序排序:
[
{
"id": 1,
"slug": "shop 1",
"stats": {
"time_stats": {
"2021": {
"1": 9.04,
"2": 8.17,
"10": 8.46,
"7": 9.35,
"11": 8.53,
"6": 8.35,
"5": 8.63,
"9": 9.13,
"3": 8.9,
"8": 7.64,
"4": 8.65,
"12": 7.45
},
}
}
},
{
"id": 2,
"slug": "shop 2",
"stats": {
"time_stats": {
"2021": {
"1": 5,
"10": 9.35,
"12": 6,
"11": 8,
"2": 3,
"3": 5,
"9": 4
},
}
}
},
{
"id": 3,
"slug": "shop 3",
"stats": {
"time_stats": {
"2021": {
"3": 9.57,
"11": 7.83,
"4": 8.94,
"2": 9.1,
"6": 8.5,
"5": 9.43,
"12": 7.93,
"10": 9.28,
"9": 9.84,
"7": 9.38,
"1": 8.91,
"8": 9.75
},
}
}
}
]
2021 对象中的每个属性代表一个月。我不知道从哪里开始,Here's what I've tried 到目前为止
db.collection.aggregate([
{
$unwind: "$stats"
},
{
$unwind: "$stats.time_stats.2021"
},
{
$group: {
_id: "$slug",
yearAvg: {
$avg: {
$sum: [
"$stats.time_stats.2021.1",
"$stats.time_stats.2021.2",
"$stats.time_stats.2021.3",
"$stats.time_stats.2021.4",
"$stats.time_stats.2021.5",
"$stats.time_stats.2021.6",
"$stats.time_stats.2021.7",
"$stats.time_stats.2021.8",
"$stats.time_stats.2021.9",
"$stats.time_stats.2021.10",
"$stats.time_stats.2021.11",
"$stats.time_stats.2021.12",
]
}
}
}
}
])
但我不确定如何继续实施。非常感谢任何帮助!
首先,您需要一种将 time_stats
散列转换为数组的方法,这将帮助您推导平均值,因为 MongoDB 已经有有用的运算符,例如$avg
. The $avg
运算符
在数组操作数上工作以 return 平均值。在你的情况下,你需要一个转换 hashmap
{
"1": 9.04,
"2": 8.17,
"10": 8.46,
"7": 9.35,
"11": 8.53,
"6": 8.35,
"5": 8.63,
"9": 9.13,
"3": 8.9,
"8": 7.64,
"4": 8.65,
"12": 7.45
}
使用 $objectToArray
运算符到键值对象数组,让我们调用新字段 time_stats_2001_average
:
{
time_stats_2001_average: [
{ "k" : "1", "v" : 9.04 },
{ "k" : "2", "v" : 8.17 },
{ "k" : "3", "v" : 8.9 },
{ "k" : "4", "v" : 8.65 },
{ "k" : "5", "v" : 8.63 },
{ "k" : "6", "v" : 8.35 },
{ "k" : "7", "v" : 9.35 },
{ "k" : "8", "v" : 7.64 },
{ "k" : "9", "v" : 9.13 },
{ "k" : "10", "v" : 8.46 },
{ "k" : "11", "v" : 8.53 },
{ "k" : "12", "v" : 7.45 }
]
}
然后使用表达式计算平均值:
{ time_stats_2001_average: { $avg: '$time_stats_2001_average.v' } }
使用排序运算符在新字段上对生成的文档进行排序:
{ $sort : { time_stats_2001_average : -1 } }
您的完整聚合管道如下所示 (Mongo Playground):
db.collection.aggregate([
{ '$addFields': {
'time_stats_2001_average': {
'$avg': {
'$map': {
'input': {
'$objectToArray': '$stats.time_stats.2021'
},
'in': '$$this.v'
}
}
}
} },
{ '$sort': { 'time_stats_2001_average': -1 } }
])
使用另一个替代管道 (Mongo Playground):
db.collection.aggregate([
{ '$addFields': {
'time_stats_2001_average': {
'$objectToArray': '$stats.time_stats.2021'
}
} },
{ '$addFields': {
'time_stats_2001_average': {
'$avg': '$time_stats_2001_average.v'
}
} },
{ '$sort' : { 'time_stats_2001_average' : -1 } }
])