如何计算MongoDb中每组的平均文档数?

问题描述 投票:0回答:3

我有一个名为 UserRecords 的 MongoDb 集合。它存储了我们用户的所有记录,每个用户可以有很多记录。

我正在尝试计算一些与每个用户的记录数相关的基本统计数据。

具体来说,我想要每个用户的记录数的平均值、中位数和众数。

到目前为止,我有一个查询,该查询按 User_Id (uid) 对所有 UserRecords 进行分组,并计算每个用户的 UserRecords 数量。

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
}

我需要查询来计算所有“计数”值的平均值。例如,假设仅产生上述结果 2 个组。我需要我的查询执行 (100 + 200) / 2 = 150 并将该值 150 打印到控制台。

有谁知道我可以在查询中添加什么来完成此操作?

*编辑,我理想的结果结构是:

{
    "mean": 1000,
    "median": 850
    "mode": 900
}
mongodb mongodb-query aggregation-framework
3个回答
2
投票

正如评论中提到的,在数据库级别计算

median
mode
可能不是一个好习惯,但只是为了热情尝试这个。

顺便说一句,它计算

count
s 的累积
uid
的中位数和众数。

db.UserRecords.aggregate([
    {
        $group: {
            _id: { "uid": "$uid" },
            count: { $sum: 1 }
        }
    },
    {
        $group: {
            _id: null,
            mean: { $avg: "$count" },
            numbers: { $push: "$count" }
        }
    },
    {
        $addFields: {
            median: {
                $function: {
                    body: function(numbers) {
                        if (numbers.length === 0) return 0;
                        numbers.sort(function(a, b) { return a - b; });
                        var half = Math.floor(numbers.length / 2);
                        if (numbers.length % 2) return numbers[half];
                        return (numbers[half - 1] + numbers[half]) / 2.0;
                    },
                    args: ["$numbers"],
                    lang: "js"
                }
            },
            mode: {
                $function: {
                    body: function(numbers) {
                        return Object.values(
                            numbers.reduce((count, e) => {
                                if (!(e in count)) {
                                    count[e] = [0, e];
                                }

                                count[e][0]++;
                                return count;
                            }, {})
                        ).reduce((numbers, v) => v[0] < numbers[0] ? numbers : v, [0, null])[1];
                    },
                    args: ["$numbers"],
                    lang: "js"
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            numbers: 0
        }
    }
]);

0
投票

您可以

group
null
作为
_id
,在这种情况下,结果是单个 将累加器表达式应用于管道中每个文档的文档

根据 MongoDB 文档

如果您指定 _id 值为 null 或任何其他常量值,$group 阶段将计算所有输入文档作为一个整体的累积值

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
        }
    }
])

0
投票

对于大多数常见统计数据,例如计数、最小值、最大值、平均值,可以通过在

$sum
 中使用 
$min
$max
$avg
$group

来实现

对于模式,可以通过

$group
$count
计算,然后
$sort
+
$limit: 1
得到最大计数。

对于中位数,可以通过最新的MongoDB v7.0

$median
算子来实现。

样本在

$facet

db.collection.aggregate([
  {
    "$facet": {
      "stat": [
        {
          $group: {
            _id: null,
            count: {
              $sum: 1
            },
            min: {
              $min: "$key"
            },
            max: {
              $max: "$key"
            },
            mean: {
              $avg: "$key"
            },
            median: {
              $median: {
                input: "$key",
                method: "approximate"
              }
            }
          }
        }
      ],
      "mode": [
        {
          "$group": {
            "_id": "$key",
            "count": {
              "$sum": 1
            }
          }
        },
        {
          $sort: {
            count: -1
          }
        },
        {
          "$limit": 1
        }
      ]
    }
  }
])

Mongo Playground(在撰写本文时,Mongo Playground 尚未支持 v7.0。您可能可以在 Playground 的后续版本中查看效果)

© www.soinside.com 2019 - 2024. All rights reserved.