mi piace la risposta da @ markus-w-Mahlberg, però, a volte, ho visto la necessità di mantenere un po 'più semplice per le persone. Come tale ho un paio di funzioni che sono sotto. Si potrebbe naturalmente avvolgere la cosa qui con operatori di massa come ha fatto lui, ma questo codice funziona allo stesso modo con i vecchi e nuovi sistemi Mongo.
function parseNS(ns){
//Expects we are forcing people to not violate the rules and not doing "foodb.foocollection.month.day.year" if they do they need to use an array.
if (ns instanceof Array){
database = ns[0];
collection = ns[1];
}
else{
tNS = ns.split(".");
if (tNS.length > 2){
print('ERROR: NS had more than 1 period in it, please pass as an [ "dbname","coll.name.with.dots"] !');
return false;
}
database = tNS[0];
collection = tNS[1];
}
return {database: database,collection: collection};
}
function insertFromCollection(sourceNS, destNS, query, batchSize, pauseMS){
//Parse and check namespaces
srcNS = parseNS(sourceNS);
destNS = parseNS(destNS);
if (srcNS == false || destNS == false){return false;}
batchBucket = new Array();
totalToProcess = db.getDB(srcNS.database).getCollection(srcNS.collection).find(query,{_id:1}).count();
currentCount = 0;
print("Processed "+currentCount+"/"+totalToProcess+"...");
db.getDB(srcNS.database).getCollection(srcNS.collection).find(query).addOption(DBQuery.Option.noTimeout).forEach(function(doc){
batchBucket.push(doc);
if (batchBucket.length > batchSize){
db.getDB(destNS.database).getCollection(destNS.collection)insert(batchBucket);
currentCount += batchBucket.length;
batchBucket = [];
sleep (pauseMS);
print("Processed "+currentCount+"/"+totalToProcess+"...");
}
}
print("Completed");
}
/** Example Usage:
insertFromCollection("foo.bar","foo2.bar",{"type":"archive"},1000,20);
Si potrebbe, ovviamente, aggiungere un db.getSiblingDB(srcNS.database).getCollection(srcNS.collection).remove(query,true)
Se si voleva rimuovere anche i record dopo che sono stati copiati nella nuova posizione. Il codice può essere facilmente costruito in questo modo per renderlo riavviabile.
fonte
2016-05-23 12:49:20
O in strumenti dell'interfaccia utente come Robomongo db.getCollection ('source'). Find ({}). ForEach (function (doc) {db.getCollection ('target'). Insert (doc); db.getCollection (' fonte').remove (doc);}) – Arthur
@Arthur: il tuo approccio presenta due principali svantaggi. È * molto * più lento * e * è possibile che le raccolte incomplete siano difficili da sincronizzare di nuovo nel peggiore dei casi. –
Questo non ha funzionato per me. Ho provato questo su una collezione con record 50M, e ho cercato di spostare circa 25 milioni. Non è riuscito nella query di ricerca con l'errore 'Errore irreversibile in CALL_AND_RETRY_2 # Allocazione non riuscita - elaborazione esaurita della memoria'. Questo è su un server con 32 GB di memoria e i record avevano solo 5 campi. La dimensione totale dei dati della raccolta è solo di circa 5 GB. – UpTheCreek