Mongodb mapreduce排序(优化)或替代



我有几个文档看起来像这样:

{
    '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-function基本上只是返回{ count: 1 },因为我对数字不感兴趣,只是唯一的元组。

我希望能更有效率。我尝试添加sort: { 'page_id' },但它触发了一个错误-谷歌显示,我显然只能排序的关键,但因为这不是一个"原始"的关键是如何工作的?

还有,这个mapreduce有没有更快的替代方案?我知道mongodb有distinct,但从我可以收集它只适用于一个领域。group聚合函数是否相关?

聚合框架似乎更合适,因为它在本机代码中运行,而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 }
    }}
])

这在很大程度上使用了日期聚合操作符。更多细节请参见其他聚合框架操作符。

当然,如果你想对那些唯一的日期进行反向排序(这与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
    }}
])

您可能需要查看聚合框架。

查询如下:

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

将为您提供您正在查找的所有字段的唯一组合。

相关内容

  • 没有找到相关文章