如何计算MongoDb中每个组的平均文档数?
我有一个名为UserRecords的MongoDb集合。它为我们的用户存储所有记录,每个用户可以有许多记录 我试图计算与每个用户的记录数相关的一些基本统计数据 具体来说,我想知道每个用户记录数的平均值、中位数和模式 到目前为止,我有一个查询,它按用户Id(uid)对所有用户记录进行分组,并统计每个用户的用户记录数如何计算MongoDb中每个组的平均文档数?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个名为UserRecords的MongoDb集合。它为我们的用户存储所有记录,每个用户可以有许多记录 我试图计算与每个用户的记录数相关的一些基本统计数据 具体来说,我想知道每个用户记录数的平均值、中位数和模式 到目前为止,我有一个查询,它按用户Id(uid)对所有用户记录进行分组,并统计每个用户的用户记录数 db.UserRecords.aggregate([ {$group: {_id:{"uid":"$uid"}, count:
db.UserRecords.aggregate([
{$group:
{_id:{"uid":"$uid"},
count:{$sum:1}}}
])
我的查询生成的结果如下所示:
{
"_id" : {
"uid" : UUID("f22880a8-94d2-4524-a974-a2e500e2c2a2")
},
"count" : 100
}
{
"_id" : {
"uid" : UUID("1b3a3b81-d107-4345-8df5-a5ef00e23598")
},
"count" : 200
}
我需要我的查询来计算所有“计数”值的平均值。例如,假设上述结果是仅产生的两组。我需要我的查询执行(100+200)/2=150并将该值打印到控制台
有人知道我可以在查询中添加什么来实现这一点吗
*编辑,我理想的结果结构是:
{
"mean": 1000,
"median": 850
"mode": 900
}
您可以使用
null
作为\u id
对进行分组
,在这种情况下,结果是单个
将累加器表达式应用于管道中的每个文档的文档
据
如果将_id值指定为null或任何其他常量值,$group阶段将计算所有输入文档作为一个整体的累积值
正如在评论中提到的,在db级别中计算
中值和模式可能不是一个好的做法,但只是出于热情,尝试一下这个方法
顺便说一句,它的计算中位数和模式取决于uid
s的累计count
db.UserRecords.aggregate([
{
$group:{
_id:{“uid”:“$uid”},
计数:{$sum:1}
}
},
{
$group:{
_id:null,
平均值:{$avg:“$count”},
编号:{$push:$count}
}
},
{
$addFields:{
中位数:{
$function:{
正文:功能(数字){
如果(number.length==0)返回0;
sort(函数(a,b){返回a-b;});
var half=数学楼层(数字长度/2);
if(number.length%2)返回数字[一半];
返回(数字[half-1]+数字[half])/2.0;
},
参数:[“$numbers”],
朗:“js”
}
},
模式:{
$function:{
正文:功能(数字){
返回Object.values(
数字。减少((计数,e)=>{
如果(!(e计)){
计数[e]=[0,e];
}
计数[e][0]++;
返回计数;
}, {})
).reduce((数字,v)=>v[0]<数字[0]?数字:v[0,null])[1];
},
参数:[“$numbers”],
朗:“js”
}
}
}
},
{
$项目:{
_id:0,
数字:0
}
}
]);
您应该能够链接另一个聚合管道阶段,执行组+$avg。请提供预期的结果结构。@turivishal完成,谢谢,平均结果会如何?下面是模式
?看看类似的,对于中值计算,我认为这种计算应该使用客户端语言,而不是mongodb查询。中值
和模式
将需要复杂的查询,因为需要排序。在第二个$group
阶段中,这些度量需要一个包含排序“count”的字段非常清晰简洁的示例谢谢@Abdulhamid Zoubi!非常令人印象深刻,回答很好!谢谢你的提问。我也学到了一些新东西!我认为计算模式的另一种(可能更简单)方法是只做两个小组阶段。第一阶段根据用户Id对用户进行分组,然后第二阶段将根据第一阶段的“计数”字段进行分组。然后可以按降序对结果进行排序,第一个文档将包含模式。
db.UserRecords.aggregate([
{
$group: {
_id: {"uid": "$uid"},
count: {$sum: 1}
},
},
{
// will result in a single document which contains sumaries of
// the previous groups data
$group: {
_id: null,
recordsCount: {$sum: '$count'}, // the number of records in the collection
usersCount: {$sum: 1}, // i.e "groups count"
}
},
{
$project: {
mean: {$divide: ['$recordsCount', '$usersCount']}
// ... you can add other measures here
}
}
])