Mongodb mapreduce排序(优化)或替代

时间:2014-06-11 11:23:04

标签: mongodb mapreduce aggregation-framework

我有一些看起来像这样的文件:

{
    'page_id': 123131,
    'timestamp': ISODate('2014-06-10T12:13:59'),
    'processed': false
}

这些文件还有其他领域,但这些是唯一与此相关的领域。在这个集合中也是这些文档的索引:

{
    'page_id': 1
    'timestamp': -1
}

我运行一个mapreduce,返回不同的(page_id, day)结果,day是时间戳的日期部分(在上面,它将是2014-06-10)。

使用以下mapreduce完成:

function() {
    emit({ 
        site_id: this.page_id, 
        day: Date.UTC(this.timestamp.getUTCFullYear(),
                      this.timestamp.getUTCMonth(),
                      this.timestamp.getUTCDate())
    }, {
        count: 1
    });
}

reduce函数基本上只返回{​​{1}},因为我对数字并不感兴趣,只是唯一的元组。

我希望提高效率。我尝试添加{ count: 1 },但它会触发错误 - 谷歌搜索显示我显然只能按键排序,但因为这不是" raw"关键是如何工作的?

另外,这个mapreduce的替代方案是否更快?我知道mongodb有sort: { 'page_id' },但是从我可以收集它只能在一个字段上工作。 distinct聚合函数可能相关吗?

2 个答案:

答案 0 :(得分:1)

聚合框架似乎更合适,因为它在本机代码中运行,其中mapReduce在JavaScript解释器实例下运行。 MapReduce有它的用途,但通常聚合框架应该最适合于不需要特定处理的常见任务,其中只有JavaScript方法允许所需的控制:

db.collection.aggregate([
    { "$group": {
        "_id": {
           "page": "$page_id",
            "day": {
                "year": { "$year": "$timestamp" },
                "month": { "$month": "$timestamp" },
                "day": { "$dayOfMonth": "$timestamp" },
            }
        },
        "count": { "$sum": 1 }
    }}

])

这很大程度上利用了date aggregation operators。有关详细信息,请参阅其他aggregation framework operators

当然,如果你想反向排序那些独特的日期(与mapReduce会做的相反)或其他字段,那么只需在管道的末尾添加一个$sort即可:

db.collection.aggregate([
    { "$group": {
        "_id": {
           "page": "$page_id",
            "day": {
                "year": { "$year": "$timestamp" },
                "month": { "$month": "$timestamp" },
                "day": { "$dayOfMonth": "$timestamp" },
            }
        },
        "count": { "$sum": 1 }
    }},
    { "$sort": {
        "day.year": -1, "day.month": -1, "day.day": -1
    }}
])

答案 1 :(得分:0)

您可能需要查看aggregation framework

像这样查询:

collection.aggregate([
 {$group: 
    {
        _id: {
            year: { $year: [ "$timestamp" ] }, 
            month: { $month: [ "$timestamp" ] },    
            day: { $dayOfMonth: [ "$timestamp" ] },
            pageId: "$page_id"
        }               
    }
  ])

将为您提供所需字段的所有独特组合。