使用MongoDB聚合框架获取数组大小直方图的最快方法

12

我正在尝试获取一个具有不同大小数组的记录数量列表。我想要获得所有记录的数组大小分布,以便我可以构建像这样的直方图:

          | *
          | *
documents | *         *
          | *  *      *
          |_*__*__*___*__*___
            2  5  6  23  47

               Array Size

因此,原始文件看起来像这样:

{hubs : [{stuff:0, id:6}, {stuff:1"}, .... ]}
{hubs : [{stuff:0, id:6}]}`

到目前为止,使用聚合框架和 这里 的一些帮助,我想出了:

db.sitedata.aggregate([{ $unwind:'$hubs'}, 
                       { $group : {_id:'$_id', count:{$sum:1}}}, 
                       { $group : {_id:'$count', count:{$sum:1}}},
                       { $sort  : {_id: 1}}])

这似乎给了我想要的结果,但速度不太快。我想知道是否有类似的方法可以实现,而不需要进行两个分组调用。这里的语法是错误的,但我试图做的是将计数值放入第一个 _id 字段:

db.sitedata.aggregate([{ $unwind:'$hubs'}, 
                       { $group : {_id:{$count:$hubs}, count:1}},
                       { $sort  : { _id: 1 }}])

无法一次完成此操作,因为在完成第一次分组计数之前,无法开始计算/分组结果。您使用的是MongoDB的哪个版本? - Asya Kamsky
顺便问一下,需要多长时间? - Asya Kamsky
好的,我猜想可能是这种情况(不允许嵌套,只能链接)。它大约需要4秒钟,这还不错,但我希望在一秒内完成。现在我可以调整我的数据而不是调整查询。 - Scott
3
为了加快速度,一种方法是通过在推入新元素时对计数器进行增量来预先聚合总和,尽管可能还有其他方法。你的管道中有多少文档进入(是否是完整集合或者首先进行某种$match操作)? - Asya Kamsky
我首先不使用$match,因为这是一个参考数据汇总。虽然只有大约60,000条记录,但需要进行相当多的管道处理。我同意将计数添加到记录中可能是加速查询的最佳选项之一,因为可以通过删除管道中的一个$group来实现。 - Scott
1个回答

9

现在2.6版本已经发布,聚合框架支持一个新的数组操作符$size,它可以让你在不必拆分和重新分组的情况下,使用$project查询数组的大小。

db.sitedata.aggregate([{ $project:{ 'count': { '$size':'$hubs'} } }, 
                       { $group : {_id:'$count', count:{$sum:1} } },
                       { $sort  : { _id: 1 } } ] )

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