在Realtieme中处理需要多次加入的不稳定集合时,MapReduce是正确的选项吗



我需要加入两个集合。。。所以我尝试了MongoDB提供的map-reduce功能。给定以下集合:

transactions:

{ "_id": 1, "userId": 1000, "amount": 0.75, "btcAddress": "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" }
{ "_id": 2, "userId": 2000, "amount": 0.55, "btcAddress": "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW63i" }

users:

{ "_id": 1000, "username": "joe", "email": "joe@domain.com" }
{ "_id": 2000, "username": "tim", "email": "tim@domain.com" }

我需要生产这样的东西:

{ "_id": 1, "username": "joe", "email": "joe@domain.com", "amount": 0.75, "btcAddress": "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" }
{ "_id": 2, "username": "tim", "email": "tim@domain.com", "amount": 0.55, "btcAddress": "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW63i" }

文档很清楚,所以我只是定义了这样的映射函数。。。

transactions_map = function() {
    ...
}
users_map = function() {
    ...
}

以及类似这样的reduce(merge)函数:

r = function(key, values) {
  ...
}

作为最后一步,我只是调用mapReduce:

res = db.transactions.mapReduce(transactions_map, r, {out: {reduce : 'joined'}});
res = db.users.mapReduce(users_map, r, {out: {reduce : 'joined'}});

这是有效的,并产生了预期的结果。。。但也有一些考虑因素。mapReduce生成一个临时集合,在我的情况下,这会引发并发问题。我想我需要在再次调用mapRedudce之前删除临时集合。。。但是该过程可以在一小时内被许多用户同时触发多次。mapReduce似乎是为统计而设计的,而我需要一些非常类似于SQL join的实时内容,因为transactions集合经常更改。

mapReduce的替代品吗?或者至少有实现策略来处理像我这样的用例吗?

如果只是以连接为例,我认为mapReduce是不必要的
我试着走这条路。

var result = [];
db.transactions.find().forEach(function(e) {
    var user = db.users.findOne({_id: e.userId}, {_id:0});
    delete e.userId;
    if (user) {
        for (var x in user) {
            e[x] = user[x];
        }
    }
    result.push(e);
});

如果结果很大,并且要保存到临时集合中,则可以在循环中将新文档保存到名为new ObjectId().str的集合中,以避免同时发生影响。

相关内容

  • 没有找到相关文章

最新更新