mongodb使用map reduce从其他集合中插入嵌入文档海量集合

Posted

技术标签:

【中文标题】mongodb使用map reduce从其他集合中插入嵌入文档海量集合【英文标题】:mongodb insert embedded documents from other collections massive collections using map reduce 【发布时间】:2014-12-05 00:51:05 【问题描述】:

我将获得的这些文件每个至少有一百万行,最多 15 亿行。当我得到它时,数据是标准化的。我需要一种将其存储在 one 文档中的方法。在大多数情况下,我不是 100% 将如何将数据提供给我。它可以是 csv、固定宽度文本文件或 tsv 或其他。

目前我有一些从一些示例 csv 导入的集合。

下面是我的数据缺失字段的小表示

在我的 beneficaries.csv 中,数据重复

beneficaries.csv 超过 600 万条记录

record # 1
"userid":"a9dk4kJkj",
 "gender":"male",
 "dob":20080514,
 "start_date":20000101,
 "end_date":20080227

record # 2
"userid":"a9dk4kJkj",
 "gender":"male",
 "dob":20080514,
 "start_date":20080201,
 "end_date":00000000

 same user different start and end dates

claims.csv 超过 2 亿条记录

"userid":"a9dk4kJkj",
     "date":20080514,
     "code":"d4rd3",
     "blah":"data"

lab.csv 超过 1000 万条记录

"userid":"a9dk4kJkj",
     "date":20080514,
     "lab":"mri",
     "blah":"data"

根据我有限的知识,我有三个选择

    对文件进行排序,从数据文件中读取我们的 c++ 成员对象中的 x 数量,在 y 处停止,将成员插入 mongodb,继续从 y 开始为 x 个成员,直到我们完成。这是测试过并且工作,但是对如此大量的文件进行排序会导致我们的机器好几个小时。

      加载数据到sql,一一读入c++成员对象,批量加载mongo中的数据。经过测试并且可以工作,但是我非常想避免这种情况。

      在单独的集合中加载 mongo 中的文档,并执行不带参数的映射缩减以写入集合。我在每个文件自己的集合中加载了文档(如上所示)。不幸的是,我是 mongo 的新手,并且在截止日期前。减少地图的概念对我来说很难理解和实施。我已阅读文档并尝试在堆栈溢出时使用此答案MongoDB: Combine data from multiple collections into one..how?

输出 member 集合应如下所示。

"userid":"aaa4444",
 "gender":"female",
 "dob":19901225,
 "beneficiaries":["start_date":20000101,
                  "end_date":20080227,
                  "start_date":20008101,
                  "end_date":00000000],
"claims":["date":20080514,
         "code":"d4rd3",
         "blah":"data",
        "date":20080514,
         "code":"d4rd3",
         "blah":"data"],
"labs":["date":20080514,
         "lab":"mri",
         "blah":"data"]

将数据加载到 sql、用 c++ 读取并插入 mongodb 的性能是否会超过 map reduction?如果是这样,我会坚持这种方法

【问题讨论】:

【参考方案1】:

恕我直言,您的数据是 map-reduce 的良好候选者,因此最好选择选项 3:在 3 个单独的集合中加载 mongo 中的文档:beneficiariesclaimslabs 并执行 map-减少每个集合上的 userid 键。最后,使用 userid 键上的 find 和 insert 将 3 个集合中的数据整合到单个集合中。

假设您将beneficiaries.csv 加载到集合beneficiaries 中,这是受益人的map-reduce 示例代码:

mapBeneficiaries = function() 
    var values = 
        start_date: this.start_date,
        end_date: this.end_date,
        userid: this.userid,
        gender: this.gender,
        dob: this.dob
    ;
    emit(this.userid, values);
;

reduce = function(k, values) 
  list =  beneficiaries: [], gender : '', dob: '';
  for(var i in values) 
    list.beneficiaries.push(start_date: values[i].start_date, end_date: values[i].end_date);
    list.gender = values[i].gender;
    list.dob = values[i].dob;
  
  return list;
;

db.beneficiaries.mapReduce(mapBeneficiaries, reduce, "out": "reduce": "mr_beneficiaries");

mr_beneficiaries 中的输出将是这样的:


    "_id" : "a9dk4kJkj",
    "value" : 
        "beneficiaries" : [ 
            
                "start_date" : 20080201,
                "end_date" : 0
            , 
            
                "start_date" : 20080201,
                "end_date" : 0
            
        ],
        "gender" : "male",
        "dob" : 20080514
    

做同样的事情来获得mp_claimsmp_labs。然后融入singledocuments

db.mr_beneficiaries.find().forEach(function(doc) 
    var id = doc._id;
    var claims = db.mr_claims.findOne("_id":id);
    var labs = db.mr_lab.findOne("_id":id);
    db.singledocuments.insert("userid":id,
                         "gender":doc.value.gender,
                         "dob":doc.value.dob,
                         "beneficiaries":doc.value.beneficiaries,
                         "claims":claims.value.claims,
                         "labs":labs.value.labs);
);

【讨论】:

我不能使用地图缩减来插入声明和实验室?那不会跑得更快 我也会发现一个人不会这样做,有多个索赔和多个实验室 mapreduce 之后,每个用户 ID 都会有一个声明/实验室列表,所以 findOne 没问题 您可以使用 mapreduce 通过设置相同的 "out" 将索赔和实验室插入到 mr_beneficiaries 的同一文档中。但是输出格式不是你想要的 我认为对我来说最好的解决方案是将每个 csv 放在一个集合中,然后使用 map reduce by id 并形成新的集合。由于用户 id 被全部使用,这应该可以正常工作。感谢您提供了有效的受益示例并演示了我如何在这些数据上使用 map reduce。在我对我熟悉的数据运行您的工作示例之前,我很难从文档中掌握这个概念

以上是关于mongodb使用map reduce从其他集合中插入嵌入文档海量集合的主要内容,如果未能解决你的问题,请参考以下文章

mgo 和 mongodb 的 i/o 超时

MongoDB下Map-Reduce使用简单翻译及示例

MongoDB:将来自多个集合的数据合并为一个..如何?

MongoDB--MapReduce分布统计s

如何在 MongoDB 和 PHP 中的 Map Reduce 查询中使用说明

MongoDB Map Reduce