MongoDB - 如何使用MapReduce将一个集合中的值合并到另一个集合的多个键上的另一个集合中?

时间:2014-07-24 14:19:44

标签: mongodb mapreduce

我有两个MongoDB个集合:第一个集合包含不同ID的频率信息,并在下面显示(截断形式):

[
    {
        "_id" : "A1",
        "value" : 19
    },
    {
        "_id" : "A2",
        "value" : 6
    },
    {
        "_id" : "A3",
        "value" : 12
    },
    {
        "_id" : "A4",
        "value" : 8
    },
    {
        "_id" : "A5",
        "value" : 4
    },
    ...
]

第二个集合更复杂,并包含第一个集合中列出的每个_id的信息(在第二个集合中称为frequency_collection_id),但frequency_collection_id可能是在每个记录的两个列表(info.details_oneinfo.details_two)内:

[
    {
        "_id" : ObjectId("53cfc1d086763c43723abb07"),
        "info" : {
            "status" : "pass",
            "details_one" : [ 
                {
                    "frequency_collection_id" : "A1",
                    "name" : "A1_object_name",
                    "class" : "known"
                }, 
                {
                    "frequency_collection_id" : "A2",
                    "name" : "A2_object_name",
                    "class" : "unknown"
                }
            ],
            "details_two" : [ 
                {
                    "frequency_collection_id" : "A1",
                    "name" : "A1_object_name",
                    "class" : "known"
                }, 
                {
                    "frequency_collection_id" : "A2",
                    "name" : "A2_object_name",
                    "class" : "unknown"
                }
            ],
        }
    }
    ...
]

我要做的是将频率信息(从第一个集合)合并到第二个集合中,实际上创建了一个看起来像这样的集合:

[
    {
        "_id" : ObjectId("53cfc1d086763c43723abb07"),
        "info" : {
            "status" : "pass",
            "details_one" : [ 
                {
                    "frequency_collection_id" : "A1",
                    "name" : "A1_object_name",
                    "class" : "known",
                    **"value" : 19**
                }, 
                {
                    "frequency_collection_id" : "A2",
                    "name" : "A2_object_name",
                    "class" : "unknown",
                    **"value" : 6**
                }
            ],
            "details_two" : [ 
                {
                    "frequency_collection_id" : "A1",
                    "name" : "A1_object_name",
                    "class" : "known",
                    **"value" : 19**
                }, 
                {
                    "frequency_collection_id" : "A2",
                    "name" : "A2_object_name",
                    "class" : "unknown",
                    **"value" : 6**
                }
            ],
        }
    }
    ...
]

我知道MongoDB的MapReduce功能应该可以做到这一点,但我见过的所有例子对我的收藏结构来说都太小了,或者回答的问题不同于我&# 39;我正在寻找。

有没有人有任何指针? 如何将我的频率信息(来自我的第一个集合)合并到记录中(在我的第二个集合的每个记录中的两个列表中)?

我知道这或多或少是JOINMongoDB不支持,但从我的阅读中看,这似乎是MapReduce的一个主要示例。

我尽我所能学习Mongo,所以如果我的问题太天真,请原谅我。

1 个答案:

答案 0 :(得分:1)

与所有MongoDB操作一样,MapReduce始终只在单个集合上运行,无法从另一个集合获取信息。因此,您首先需要将两个集合转储为一个集合。您的文档有不同的_id,因此它们在同一个集合中共存应该不是问题。

然后你做一个MapReduce,其中地图函数emit是他们共同key的两种文件,这是他们的频率ID。

您的 reduce 功能将为每个密钥接收两个文档的数组:您收到的两个文档。然后,您只需将这两个文档合并为一个。请记住,reduce函数可以按任何顺序接收这两个文档。也可能发生它被调用部分结果(只有两个文档中的一个)或已经完成的结果。你需要优雅地处理这些案件!一个好的实现可能是创建一个新对象,然后迭代输入文档,将所有现有相关字段及其值复制到新对象,因此生成的对象是输入文档的合并。