我有一些看起来像这样的文件:
{
'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
聚合函数可能相关吗?
答案 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"
}
}
])
将为您提供所需字段的所有独特组合。