我有两个集合,都有这样的结构:
id trips_in
1 5
2 10
id trips_out
1 6
2 8
我的问题是如何将它们组合成一个像这样的集合:
id trips_in trips_out
1 5 6
2 10 8
我发现了mapReduce
,但它的功能看起来比我需要的更多。我写了以下查询:
tripsInMap = function() {
var values = {
trips_in: this.trips_in
};
emit(this._id, values);
};
tripsOutMap = function() {
var values = {
trips_out: this.trips_out
};
emit(this._id, values);
};
reduce = function(key, values) {
var result = {
"trips_out" : "",
"trips_in" : ""
};
values.forEach(function(value) {
if(value.trips_out !== null) {result.trips_out = value.trips_out;}
if(value.trips_in !== null) {result.trips_in = value.trips_in;}
});
return result;
}
db.tripsIn.mapReduce(tripsInMap, reduce, {"out": {"reduce": "joined"}});
db.tripsOut.mapReduce(tripsOutMap, reduce, {"out": {"reduce": "joined"}});
但是我最终得到了"trips_in": undefined
。我想知道是否有更好的方法。
答案 0 :(得分:1)
虽然这可能不是最快的方法,但你可以尝试这样的事情:
// Create the new collection with data from the tripsIn collection
db.tripsIn.find().forEach( function(trip) {
db.tripsJoined.insert({ _id: trip._id, trips_in: trip.trips_in, trips_out: 0 });
})
// Update the trips_out field in the tripsJoined collection
// using upsert:true to insert records that are not found
db.tripsOut.find().forEach( function(trip) {
db.tripsJoined.update(
{ _id: trip._id},
{$inc: {trips_in: 0, trips_out: trip.trips_out}},
{upsert: true});
})
第一行将遍历tripsIn
集合中的每个文档,并在tripsJoined
集合中插入相应的文档并设置trips_out
字段。
第二行将遍历tripsOut
集合,对于每个文档,它将使用tripsJoined
值更新相应的trips_out
文档。
请注意,我添加了{$inc: {trips_in: 0
...和upsert:true
。这样做是为了如果tripsOut
集合中存在任何在tripsIn
集合中没有相应_id值的行程文档,则会插入文档并初始化trips_in
字段到0。