【问题标题】:Use mongodb aggregation framework to group by length of array使用 mongodb 聚合框架按数组长度分组
【发布时间】:2013-07-31 01:47:55
【问题描述】:

我有一个看起来像这样的集合:

{
    "_id": "id0",
    "name": "...",
    "saved_things": [
        { ... },
        { ... },
        { ... },
    ]
}
{
    "_id": "id1",
    "name": "...",
    "saved_things": [
        { ... },
    ]
}
{
    "_id": "id2",
    "name": "...",
    "saved_things": [
        { ... },
    ]
}

等等……

我想使用 mongodb 的聚合框架来得出一个直方图结果,该结果告诉有多少用户拥有一定数量的saved_things。例如,对于上面的数据集,它可能会返回如下内容:

{ "_id": 1, "count": 2 },
{ "_id": 3, "count": 1 }

我尝试了各种聚合函数组合,如下所示,但没有一个能正确运行。 (我觉得我做错了。)

collection.aggregate([
    { $unwind: "$saved_things" },
    { $group: "$_id", count: { $sum: 1 } } },
    { $group: "$count", number: { $sum: 1 } } },
    { $sort: { number: -1 } }
], function(err, result) {
    console.log(result);
});

这可以通过 Mongo 的聚合框架实现,还是使用 map reduce 函数会更好?

【问题讨论】:

  • 你的意思是有多少用户有一定数量的saved_things subcollectin?给定saved_thing,您想知道哪些用户拥有saved_things 以及多少?是吗?
  • 嗯,我的措辞似乎令人困惑,对此感到抱歉!我认为示例输出最能描述我正在寻找的内容,但我会再次尝试描述它。我想为集合中的每个用户获取saved_things 中的对象数,并汇总该计数的频率。它用于生成用户数量的直方图saved_things(如果有意义的话)。让我知道这是否仍然令人困惑。

标签: mongodb mapreduce aggregation-framework


【解决方案1】:

好的,知道了!开始了。聚合管道基本上是这样的:

{
    $unwind: "$saved_things"
},
{
    $group: {
        _id: "$_id",
        size: {
            $sum: 1
        }
    }
},
{
    $group: {
        _id: "$size",
        frequency: {
            $sum: 1
        }
    }
},
{
    $project: {
        size: "$_id",
        frequency: 1,
        _id: 0
    }
}

展开saved_things数组,然后按文档_id分组并计数,这样就可以得到数组的大小。现在很容易,按size 分组并计算频率。使用项目将_id字段重命名为size

【讨论】:

  • 看起来真的很接近。我将其作为输出:gist.github.com/stevenleeg/2b1a2ee9c5400f5f3089
  • 开个玩笑!我正在回显results 而不是result,这导致了问题。我看到的唯一不太有效的是没有频率 0 的数据。对此有什么可以做的吗?
  • 我不相信这种聚合将包含零长度数组的文档的频率值。为什么我的频率总数与我的特定收集计数不匹配,我一时摸不着头脑。
【解决方案2】:

你可以使用 $size 键 示例

query :

[{ 
   $group: {
     _id:{$size:'$saved_things'},
     total: { $sum: 1 },
   }
}]

output:
[{ _id: 4, total: 2 }]

【讨论】:

    猜你喜欢
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2014-07-08
    • 1970-01-01
    • 2015-06-07
    • 2014-08-19
    相关资源
    最近更新 更多