【问题标题】:Join operation with MongoDB MapReduce使用 MongoDB MapReduce 加入操作
【发布时间】:2011-08-12 18:41:04
【问题描述】:

我之前一直在使用 MapReduce 执行经典的 MR 操作,相当于 SQL 中的 GROUP BY。

我想知道在概念上是否可以使用 MapReduce 执行 JOIN 操作。知道如何实施吗?使用 MapReduce 进行这种操作有意义吗?

谢谢!

【问题讨论】:

  • 你的意思是JOIN操作吗?

标签: mongodb mapreduce


【解决方案1】:

MongoDB 不支持连接等关系操作。相反,您可以通过在外部文档中嵌入要加入的行来对数据进行非规范化。因此,您可以拥有一个具有此架构的 products 集合,而不是将 Products 加入 Sales:

产品

{
    _id: 123,
    name: "Widget",
    price: 9.99
    sales:
    [ 
        { id:1, date: "20100316", howMany: 2 },
        { id:2, date: "20100316", howMany: 5 }
    ]
}

然后,每当您检索产品时,您也会获得其销售数据,因此无需在其他地方加入或查找信息。

或者,您可以像使用关系数据库一样将其拆分为两个集合,然后使用附加查询来获取产品的销售额,如下所示:

SQL:SELECT Sales WHERE ProductId = 123

MongoDB:db.sales.find( { productid: 123 } )

产品

{
    _id: 123,
    name: "Widget",
    price: 9.99
}

销售

{
    id: 1,
    productid: 123,
    date: "20100316",
    howMany: 2 
}

{
    id: 2,
    productid: 123,
    date: "20100316",
    howMany: 5
}

【讨论】:

  • 我喜欢 MongoDB,但这种数据结构对我来说感觉不正确。因为如果您只想显示包含产品信息的页面,您会关心包含该产品销售的所有信息的 Gigs 数据。这不是一种表演杀手吗?
  • @MaximilianRuta 如果您处理大量关系数据,最好使用 SQL 数据库。例如,Diaspora 正是出于这个原因从 MongoDB 迁移到 MySQL。见MongoDB to MySQL the How and the Why by Sarah Mei
【解决方案2】:

我的方法如下:

看看 hadoop 我找到了 CompositeInputFormat 方法 简而言之,它需要两个或多个集合作为 map-reduce 作业的输入

根据我的调查,mongodb 还没有提供这个。 mongodb mapReduce 一次在一个集合上执行。(如果我穿着,请更正)

所以我决定把需要加入的集合 在一个集合中,我将为“sql right join”执行 mapreduce

这是来自我的日志记者项目。 第一个阶段 map-reduce 足以在“没有时钟”的情况下执行右连接。 第二阶段map-reduce的目的是排除由时钟场引起的多余的右连接。

db.test.drop();
db.test.insert({"username" : 1, "day" : 1, "clock" : 0 });
db.test.insert({"username" : 1, "day" : 1, "clock" : 1 });
db.test.insert({"username" : 1,  startDay : 1,endDay:2, "table" : "user" });

//startDay : 1,endDay:2 are used to define the employers working day (join to company - left the company)
//you can use an array instedad of array here. for example day:[1,2,3, ...]

m1 = function(){
   if( typeof this.table!= "undefined" && this.table!=null){
       username = this.username;
       startDay = this.startDay;
       endDay   = this.endDay;
       while(startDay<=endDay){
           emit({username:username,day:startDay},{clocks:["join"]});
          // emit({username:username,day:startDay},1);
           startDay++;
       }
   }else{
       emit({username:this.username,day:this.day},{clocks:[this.clock]});
   }
}
r1 = function(key,values){
    result = {clocks:[]}
    values.forEach(function(x){
        result.clocks = x.clocks.concat(result.clocks);
        result.clocks=result.clocks.filter(function(element, index, array){
            return element!="join";            
        })
    })
    return result;
}

db.test.mapReduce(m1,r1,{out:"result1"})
db.test.find();
db.result1.find();

m2=function(){
   key=this._id;
   this.value.clocks.forEach(function(x){
       key.clock=x;
       emit(key,1);       
   })   
}
r2 = function(key,values){
    value=0;
    values.forEach(function(x){
        value+=1;      
    })
    return result;
}

db.result1.mapReduce(m2,r2,{out:"result2"})
db.test.find();
db.result2.find();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-20
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 2013-08-23
    相关资源
    最近更新 更多