是否可以在Mongodb MapReduce中进行Reduce-Side连接
我读到Hadoop框架支持Reduce-Side、Replicated和Composite等连接。Mongodb中是否有对这些连接的支持 对于我来说,用例是记录的每个用户都有一组事件及其发生情况。这是一个很好的例子是否可以在Mongodb MapReduce中进行Reduce-Side连接,mongodb,mapreduce,Mongodb,Mapreduce,我读到Hadoop框架支持Reduce-Side、Replicated和Composite等连接。Mongodb中是否有对这些连接的支持 对于我来说,用例是记录的每个用户都有一组事件及其发生情况。这是一个很好的例子 {_id: uniqueEventId, event: login, userId: abc} {_id: abc, city: "SF", state: CA, customfield1: value1...} 还有另一个集合包含有关用户的详细信息,用户的属性不是固定的。这是一
{_id: uniqueEventId, event: login, userId: abc}
{_id: abc, city: "SF", state: CA, customfield1: value1...}
还有另一个集合包含有关用户的详细信息,用户的属性不是固定的。这是一份样本文件
{_id: uniqueEventId, event: login, userId: abc}
{_id: abc, city: "SF", state: CA, customfield1: value1...}
我需要的结果是事件、userId和用户详细信息的聚合。样本
{userId: abc, event: login, count:23, city: SF, state: CA}
因此,我可以根据具有最多登录事件和类似查询的州或城市进行查询
我考虑将用户文档作为事件文档的一部分嵌入,但如果用户属性发生变化,我需要更新所有事件集合,这将是一个巨大的过程
我看了一下从这个集合中合并两个集合的方法,但这并不是很有用,因为我需要在其上运行reduce函数的键是一个复合键(userId+事件)。我想指出的是,这个连接不能实时用于你的应用程序,这样做会破坏MongoDB,但是,是的;有一种方法可以映射并减少连接 在您的第一个MR中,获得:
{_id: abc, city: "SF", state: CA, customfield1: value1...}
您只需发出此行并将其写入新集合。然后在您的第二个MR中,您会得到:
{userId: abc, event: login, count:23, city: SF, state: CA}
您将userId
实际\u id
:
var map = function(){
emit(this.userId, {this.event, //etc});
}
或复合键:
var map = function(){
emit({o: this.userId, e: this.event}, {this.event, //etc});
}
然后,您可以按正常方式减少,但可以更改命令,或者更确切地说是调用服务器,以便MR中的out
选项实际指向第一个MR的结果,在out
选项上添加reduce
或merge
命令,以使两个集合在重复的\u id
上合并:
db.col.mapreduce( map, reduce, { out: {merge:collection_from_first_mr} })
这就是它的工作原理
回到我在这个答案开头的第一个通知。这不是SQL联接,不应将其视为SQL联接。JS引擎是:
- 慢
- 单螺纹
- 它实际上不是MongoDB或服务器端,而是MongoDB的内置JS引擎
{_id: uniqueEventId, event: login, userId: abc, state: '', city: ''}
并在此基础上进行聚合。我知道这种联接对性能的影响,因此这些联接将作为后台作业运行。如果我从一个集合中发出复合键,而另一个集合中没有复合键中的字段,那么我在这里无法执行的操作。例如:
{userId:abc,event:login}
是collection1的复合键,而{userId:abc,event:null}
是collection2的复合键。在这种情况下,似乎根本不可能加入。是吗?@Sundar Yea我没有想到,因为有一次我很快就写下了答案。请注意,我不认为您在这里使用复合键,因为您希望所有登录事件及其用户详细信息正确吗?或者只是所有事件及其用户详细信息?无论哪种方式,它听起来都像是事件集合独有的事件,在SQL技术中加入也不太好。@Sundar您通常只需要用户id就可以进行此连接,然后在完成此操作后进行后期聚合以加入所需的数据,这是此想法的一大缺陷,即您必须有效聚合两次(就像一个真正的连接)。