2017-05-18 35 views
0

有兩個集合,都具有這樣的結構:追加收藏我一起

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

您能否添加查詢,您可以更新查詢以實現此目的。此外,這裏是鏈接做同樣的** https://www.npmjs.com/package/zip-array ** – tom

+0

@anoop我加了我的查詢。我不明白這個軟件包是如何相關的。 – ffritz

回答

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集合,並且對於每個文檔,它將使用trips_out值更新相應的tripsJoined文檔。

請注意,我添加了{$inc: {trips_in: 0 ...和upsert:true。這樣做是爲了使tripsOut集合中存在tripsIn集合中沒有對應_id值的任何行程文檔時,將插入文檔並將trips_in字段初始化爲0.

+0

非常好的解決方案,非常感謝! – ffritz