MongoDB获取分组数据的所有记录

时间:2012-08-21 14:51:27

标签: ruby-on-rails mongodb mongoid grouping

我试图设置一个简单的要点来解释我的问题和我想要的here

它肯定不会复制我的确切文档结构(这是完全不同的),但会帮助您轻松理解我的问题。

更新

Gist被意外删除,因此更新了问题:

假设我有这个结构

    _id  name  birthdate
    ...  john  10 aug
    ...  doe   11 aug
    ...  foo   11 aug
    ...  bar   12 aug
    ...  baz   12 aug
    ...  bak   12 aug
    ...  buzz  13 aug

我想找到共享相同生日的所有文档,因此我的结果集将在那里:

    _id  name  birthdate
    ...  doe   11 aug
    ...  foo   11 aug
    ...  bar   12 aug
    ...  baz   12 aug
    ...  bak   12 aug

我还想以某种方式获得针对每个文档的日期共享记录的count()。所以,像这样

    _id  name  birthdate  count
    ...  doe   11 aug     2
    ...  foo   11 aug     2
    ...  bar   12 aug     3
    ...  baz   12 aug     3
    ...  bak   12 aug     3

到目前为止,我所尝试的只是mapReduce,但我只能得到:

    _id     value
    11 aug  {count: 2}
    12 aug  {count: 3}

1 个答案:

答案 0 :(得分:3)

使用MongoDB 2.2中的新Aggregation Framework可以更轻松地实现您的结果。

以下示例使用的是MongoDB shell,但类似的方法可以使用Mongoid。

假设数据设置为:

db.users.insert({'name': 'john', 'birthdate':'10 aug'});
db.users.insert({'name': 'doe',  'birthdate':'11 aug'});
db.users.insert({'name': 'foo',  'birthdate':'11 aug'});
db.users.insert({'name': 'bar',  'birthdate':'12 aug'});
db.users.insert({'name': 'baz',  'birthdate':'12 aug'});
db.users.insert({'name': 'bak',  'birthdate':'12 aug'});
db.users.insert({'name': 'buzz', 'birthdate':'13 aug'});

以下是聚合命令的注释示例:

db.users.aggregate(
    // Group and count documents by same birthdate
    { $group: {
        '_id' : '$birthdate',
        'name': { $addToSet: '$name' },
        'count': { $sum: 1 },
    }},

    // Only match documents with at least one duplicate
    { $match : {
        'count' : { $gt: 1 }
    }},

    // Unwind the grouped documents so there is one per name
    { $unwind : '$name' },

    // Sort results by _id and name
    { $sort : {
        '_id': 1,
        'name': 1,
    }}
)

..和结果:

{
    "result" : [
        {
            "_id" : "11 aug",
            "name" : "doe",
            "count" : 2
        },
        {
            "_id" : "11 aug",
            "name" : "foo",
            "count" : 2
        },
        {
            "_id" : "12 aug",
            "name" : "bak",
            "count" : 3
        },
        {
            "_id" : "12 aug",
            "name" : "bar",
            "count" : 3
        },
        {
            "_id" : "12 aug",
            "name" : "baz",
            "count" : 3
        }
    ],
    "ok" : 1
}