聚合对象的嵌套数组实例计数

时间:2014-11-27 16:11:50

标签: mongodb aggregation-framework

我试图以这种方式聚合日志,因此我可以计算特定用户偏爱关键字的次数。我想出的是查询:

db.a.aggregate([
    {$unwind: "$keywords"},
    {$group : {_id : {word : "$keywords", user : "$favorited_by"}, count : {$sum : 1}}}
]);

但它会产生输出:

{ "_id" : { "word" : "another", "user" : "too_creepy" }, "count" : 1 }
{ "_id" : { "word" : "test", "user" : "too_creepy" }, "count" : 2 }

虽然我想得到这样的东西:

INPUT

{
    _id: ObjectId("5475cf117ccee624583ba94a"),
    favorited_by: "too_creepy",
    keywords: [
        "test"
    ]
},
{
    _id: ObjectId("5475cf117ccee624583ba949"),
    favorited_by: "too_creepy",
    keywords: [
        "test"
    ]
},
{
    _id: ObjectId("5475cf117ccee624583ba949"),
    favorited_by: "too_creepy",
    keywords: [
        "anotherone"
    ]
},
{
    _id: ObjectId("5475cf117ccee624583ba09a"),
    favorited_by: "hello_world",
    keywords: [
        "test"
    ]
}

输出

{
    favorited_by: "too_creepy",
    keywords: [
        {keyword: "test", count: 2},
        {keyword: "anotherone", count: 1}
    ]
},
{
    favorited_by: "hello_world",
    keywords: [
        {keyword: "test", count: 1}
    ]
}

任何想法如果可以写这个查询怎么可能?

1 个答案:

答案 0 :(得分:1)

您可以通过在管道中添加第二个$group,然后使用最终$project来重新整理输出,来实现这一点:

db.a.aggregate([
    {$unwind: "$keywords"},
    {$group: {_id: {word: "$keywords", user: "$favorited_by"}, count: {$sum: 1}}},
    // Group again on just user, and use $push to assemble an array of their keywords
    {$group: {
        _id: '$_id.user', 
        keywords: {$push: {keyword: '$_id.word', count: '$count'}}
    }},
    // Reshape the output
    {$project: {favorited_by: '$_id', keywords: 1, _id: 0}}
]);

输出:

{
    "keywords" : [ 
        {
            "keyword" : "anotherone",
            "count" : 1
        }, 
        {
            "keyword" : "test",
            "count" : 2
        }
    ],
    "favorited_by" : "too_creepy"
}, 
{
    "keywords" : [ 
        {
            "keyword" : "test",
            "count" : 1
        }
    ],
    "favorited_by" : "hello_world"
}