MongoDB聚合:统计数组/集合大小

12

我的问题如下:

模型:

{ application: "abc", date: Time.now, status: "1" user_id: [ id1, id2, id4] }

{ application: "abc", date: Time.yesterday, status: "1", user_id: [ id1, id3, id5] }

{ application: "abc", date: Time.yesterday-1, status: "1", user_id: [ id1, id3, id5] }

我需要在一段时间内计算唯一的user_ids数量。

预期结果:

{ application: "abc", status: "1", unique_id_count: 5 }

我目前使用聚合框架,在mongodb外部计数ids。

{ $match: { application: "abc" } }, { $unwind: "$users" }, { $group: { _id: { status: "$status"}, users: { $addToSet: "$users" } } }

我的用户id数组非常大,所以必须迭代日期,否则将会达到文档最大限制(16mb)。

我还可以通过以下方式进行$group:

{ year: { $year: "$date" }, month: { $month: "$date" }, day: { $dayOfMonth: "$date" }

但我还是会受到文档大小限制。

在mongodb中有没有可能计算集合的大小?

谢谢


你的每个用户是否拥有超过16MB的ID或者你所有记录是否总共超过了16MB的数据?如果是后者,则可以尝试将结果刷新到输出集合中。 - cubbuk
用户数组/集大小超过一千,并且用户ID类似于对象ID(50b9d949816e6e37060005c2)。以前的版本使用map/reduce和输出集合。速度非常慢。在内存中计数比编写输出集合更快。 - user2019059
当您进行表扫描并仅检索应用程序和userId字段时,性能如何?当然,在内存中计数更快,但是您在Mongo方面有限制。据我所知,如果输出不适合内存,则刷新到磁盘或进行表扫描是您的唯一选择。 - cubbuk
1
性能还可以。我只希望有一种方法来计算数组大小而不返回整个内容。 - user2019059
3个回答

25
以下内容将返回每个应用程序的唯一用户数。这将使用MongoDB的管道功能对一次分组操作的结果进行另一次分组操作。
{ $match: { application: "abc" } }, 
{ $unwind: "$users" }, 
{ $group: { _id: "$status", users: { $addToSet: "$users" } } }, 
{ $unwind:"$users" }, 
{ $group : {_id : "$_id", count : {$sum : 1} } }
希望在后续的Mongo版本中能够通过一个命令来给出投影下数组的大小,以更加简便的方式完成此操作。代码示例:{$project: {id: "$_id", count: {$size: "$uniqueUsers"}}} 更多细节请参考https://jira.mongodb.org/browse/SERVER-4899。祝好!

3
这是在版本2.5.3中新增的内容(目前是开发版本)。 - Nevena
你的例子 {$project: {id: "$_id", count: {$size: "$uniqueUsers"}}} 在2.6版本中对我很有用。谢谢! - Matt Wilson

2

抱歉我有点晚了。简单地按'user_id'分组并使用一个微不足道的聚合函数计算结果就可以了,这样不会遇到文档大小限制。

[
    {$match: {application: 'abc', date: {$gte: startDate, $lte: endDate}}},
    {$unwind: '$user_id'},
    {$group: {_id: '$user_id'}},
    {$group: {_id: 'singleton', count: {$sum: 1}}}
];

它也不能满足问题“我需要在一段时间内计算唯一的user_id数量”,OP已经知道如何为每个时间段进行计算。 - Asya Kamsky

1
使用$size获取集合的大小。
[
    {
        $match: {"application": "abc"}
    },
    {
        $unwind: "$user_id"
    },
    {
        $group: {
            "_id": "$status",
            "application": "$application",
            "unique_user_id": {$addToSet: "$user_id"}
        }
    },
    {
        $project:{
            "_id": "$_id",
            "application": "$application",
            "count": {$size: "$unique_user_id"}
        }
    }
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接