我想做点什么
SELECT e1.sender
FROM email as e1, email as e2
WHERE e1.sender = e2.receiver;
但是在MongoDB中。我找到了许多关于JOIN的论坛,可以通过MongoDB中的MapReduce实现,但我不明白如何在这个带有自联接的例子中做到这一点。
我在考虑这样的事情:
var map1 = function(){
var output = {
sender:db.collectionSender.email,
receiver: db.collectionReceiver.findOne({email:db.collectionSender.email}).email
}
emit(this.email, output);
};
var reduce1 = function(key, values){
var outs = {sender:null, receiver:null
values.forEach(function(v) {
if(outs.sender == null){
outs.sender = v.sender
}
if(outs.receivers == null){
outs.receiver = v.receiver
}
});
return outs; }};
db.email.mapReduce(map2,reduce2,{out:'rec_send_email'})
创建2个新集合 - 仅包含接收者电子邮件的collectionReceiver和仅包含发件人电子邮件的collectionSender
OR
var map2 = function(){
var output = {sender:this.sender,
receiver: db.email.findOne({receiver:this.sender})}
emit(this.sender, output);
};
var reduce2 = function(key, values){
var outs = {sender:null, receiver:null
values.forEach(function(v){
if(outs.sender == null){
outs.sender = v.sender
}
if(outs.receiver == null){
outs.receiver = v.receiver
}
});
return outs; };};
db.email.mapReduce(map2,reduce2,{out:'rec_send_email'})
但它们都没有工作,我不太理解这个MapReduce。有人可以向我解释一下吗?我受到了这篇文章http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/的启发。
另外,我需要用Java编写它。有什么方法可以解决它吗?
答案 0 :(得分:3)
如果您在使用MongoDB时需要实现“自联接”,那么您可能错误地(或次优地)构建了架构。
在MongoDB(以及一般的noSQL)中,架构结构应该反映您需要针对它们运行的查询。
看起来您正在假设一组电子邮件,其中每个文档都有一个发件人和一个收件人,现在您想要找到所有也恰好是电子邮件接收者的发件人?唯一的方法是通过两个简单的查询,而不是通过map / reduce(这将是更复杂,更不必要的,你编写它们的方式将无法工作,因为你无法从map函数中查询)。
您正在用Java编写 - 为什么不进行两次查询 - 第一次获取所有唯一发件人,第二次查找发件人列表中的所有唯一接收者?
在shell中它将是:
var senderList = db.email.distinct("sender");
var receiverList = db.email.distinct("receiver", {"receiver":{$in:senderList}})