0

I have n collections which I need to merge - i.e. copy the documents from them into a new one or append onto a "target" collection. How do I do it in mongodb?

Daniel
  • 1,075
  • 2
  • 14
  • 26
  • copyto() in a loop – Alex Blex May 17 '17 at 14:21
  • Possible duplicate of [MongoDB: Combine data from multiple collections into one..how?](http://stackoverflow.com/questions/5681851/mongodb-combine-data-from-multiple-collections-into-one-how) – Bogdan Kobylynskyi May 17 '17 at 14:22
  • @AlexBlex That is deprecated. Also please check the [warning](https://docs.mongodb.com/manual/reference/method/db.collection.copyTo/). – Daniel May 17 '17 at 14:23
  • @BogdanKobylinsky That question is more than 6 years old, I'm looking for something now (something easier hopefully). This should be a simple task no? I have a lot of documents in both collection. – Daniel May 17 '17 at 14:24
  • It still works. If global lock is a problem, you need to write your own copier to resolve possible conflicts. – Alex Blex May 17 '17 at 14:36
  • @AlexBlex A global lock is absolutely a problem. – Daniel May 17 '17 at 14:44
  • Then follow the 5yrs old battle tested map-reduce. Map yields from read lock every 100 documents, output acquires a write lock per document. – Alex Blex May 17 '17 at 14:57

1 Answers1

0

Use mapReduce to copy documents grouping by _id:

var map = function(){
    emit(this._id, this);
};
var reduce = function(id, docs){
    // this function will be invoked only if there are more than 1 document with the same `_id`
    // resolve the conflict, e.g. return the first document, ignore everything else:
    return docs[0]; 
};

['collection1', 'collection2', 'collection3'].forEach(function(collection){
    db[collection].mapReduce(map, reduce, {out: {reduce: 'v', nonAtomic: true}});
});
Alex Blex
  • 34,704
  • 7
  • 48
  • 75