3

我想做类似的事情

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

或者

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 编写它。有什么办法可以解决吗?

4

1 回答 1

5

如果您在使用 MongoDB 时需要实现“自连接”,那么您的架构可能不正确(或次优)。

在 MongoDB(以及一般的 noSQL)中,模式结构应该反映您需要针对它们运行的​​查询。

看起来您正在假设一组电子邮件,其中每个文档都有一个发件人和一个收件人,现在您想找到所有恰好也是电子邮件收件人的发件人?做到这一点的唯一方法是通过两个简单的查询,而不是通过 map/reduce(这将更加复杂、不必要,而且您编写它们的方式不起作用,因为您无法从 map 函数中查询)。

您正在用 Java 编写 - 为什么不进行两个查询 - 第一个是获取所有唯一的发件人,第二个是查找也在发件人列表中的所有唯一的接收者?

在外壳中它将是:

var senderList = db.email.distinct("sender");
var receiverList = db.email.distinct("receiver", {"receiver":{$in:senderList}})
于 2013-04-30T03:29:33.033 回答