nel*_*rom 34 mapreduce mongodb
我正在尝试使用MongoDB来分析Apache日志文件.我已经receipts从Apache访问日志创建了一个集合.以下是我的模型外观的精简摘要:
db.receipts.findOne()
{
"_id" : ObjectId("4e57908c7a044a30dc03a888"),
"path" : "/videos/1/show_invisibles.m4v",
"issued_at" : ISODate("2011-04-08T00:00:00Z"),
"status" : "200"
}
Run Code Online (Sandbox Code Playgroud)
我编写了一个MapReduce函数,它按issued_at日期字段对所有数据进行分组.它总结了请求的总数,并提供了每个唯一路径的请求数的细分.以下是输出结果的示例:
db.daily_hits_by_path.findOne()
{
"_id" : ISODate("2011-04-08T00:00:00Z"),
"value" : {
"count" : 6,
"paths" : {
"/videos/1/show_invisibles.m4v" : {
"count" : 2
},
"/videos/1/show_invisibles.ogv" : {
"count" : 3
},
"/videos/6/buffers_listed_and_hidden.ogv" : {
"count" : 1
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何使输出看起来像这样:
{
"_id" : ISODate("2011-04-08T00:00:00Z"),
"count" : 6,
"paths" : {
"/videos/1/show_invisibles.m4v" : {
"count" : 2
},
"/videos/1/show_invisibles.ogv" : {
"count" : 3
},
"/videos/6/buffers_listed_and_hidden.ogv" : {
"count" : 1
}
}
}
Run Code Online (Sandbox Code Playgroud)
从以前的答案和评论中获取最佳效果:
db.items.find().hint({_id: 1}).forEach(function(item) {
db.items.update({_id: item._id}, item.value);
});
Run Code Online (Sandbox Code Playgroud)
来自http://docs.mongodb.org/manual/core/update/#replace-existing-document-with-new-document
"如果update参数仅包含字段和值对,则该update()方法将现有文档替换为中的文档这个update论点,除了这个_id领域."
所以你既不需要$unset value也不需要列出每个字段.
来自https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/#cursor-snapshot "在某些情况下,MongoDB游标可以多次返回同一文档....使用唯一索引此字段或这些字段使查询将返回每个文档不超过一次.使用hint()查询以显式强制查询使用该索引.
AFAIK,按照设计Mongo的map reduce会在"值元组"中吐出结果,而我没有看到任何可以配置"输出格式"的东西.也许可以使用finalize()方法.
您可以尝试运行将使用重新整形数据的后处理
results.find({}).forEach( function(result) {
results.update({_id: result._id}, {count: result.value.count, paths: result.value.paths})
});
Run Code Online (Sandbox Code Playgroud)
是的,看起来很难看.我知道.