Mongo Aggregation分组子文档

时间:2013-12-14 17:48:07

标签: mongodb mongoose aggregation-framework

我很难用MongoDB的聚合框架做一些看似简单的事情。

想象一下,您的文档看起来像这样:

[
    { a: 1, b: 2 },
    { a: 1, b: 3 },
    { a: 5, b: 6 }
]
  • 如何按字段a对文档进行分组,然后按另一个字段重新组合子文档,比如b,同时仍在计算每一步的文档总数?

对于我们的示例,结果将看起来是以下输出文档:

{
    results: [
        {
            _id: {
                a: 1
            },
            sum_a: 2,
            doc_a: [
                {
                    _id: {
                        b: 2
                    },
                    sum_b: 1
                },
                {
                    _id: {
                        b: 3
                    },
                    sum_b: 1
                }
            ]
        },
        {
            _id: {
                a: 5
            },
            sum_a: 1,
            doc_a: [
                {
                    _id: {
                        b: 6
                    },
                    sum_b: 1
                }
            ]
        }
    ]
}

我尝试过这样的事情:

printjson(db.getSiblingDB('mydb').mycollection.aggregate([
    {
        $project: {
            a: 1,
            b: 1
        }
    },
    {
        $group: {
            _id: {
                a: '$a'
            },
            sum_a: {
                $sum: 1
            },
            b: {
                $first: '$b'
            }
        }
    },
    {
        $group: {
            _id: {
                b: '$b'
            },
            sum_b: {
                $sum: 1
            }
        }
    },
    {
        $sort: {
            sum_a: 1
        }
    }
]));

但是在我做的不同测试中,它会覆盖以前的小组赛结果,错误地计算总和,等等。

所以我不确定如何处理这个问题。

1 个答案:

答案 0 :(得分:3)

如果按主字段('a')和子字段('b')组合在一起,然后仅按'a'组合(将第一步的计数相加)并将'b'推入数组(复制)从第一步开始计算,它应该产生你需要的东西:

{
    $group : {
        _id : {
            a : '$a',
            b : '$b'
        },
        count : {
            $sum : 1
        }
    }
},{
    $group : {
        _id : {
            a : '$_id.a'
        },
        count_a : {$sum: '$count'},
        doc_a : {
            $push : {
                b : '$_id.b',
                count_b : '$count'
            }
        }
    }
}