在MongoDB mapreduce中,如何展平值对象?

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)

mst*_*arn 14

目前还不行,但我建议投票支持此案例:https://jira.mongodb.org/browse/SERVER-2517.


Den*_*kov 7

从以前的答案和评论中获取最佳效果:

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()查询以显式强制查询使用该索引.


Ijo*_*nas 5

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)

是的,看起来很难看.我知道.