/// <summary> /// Migrates data and indexes of all collections of a certain database, to another /// </summary> /// <param name="sourceDatabase">Source database - Where the data will come from</param> /// <param name="targetDatabase">Target database - Where the data will go to</param> /// <param name="collectionsNameMask">Mask that will be used to decide whether one collection will be copied or not - Case Sensitive</param> /// <param name="insertBatchSize">Size (in records) of the chunk of data that will be inserted per batch</param> /// <param name="copyIndexes">True if the indexes should be copied aswell, false otherwise</param> public static void CollectionsMerge(MongoDatabase sourceDatabase, MongoDatabase targetDatabase, String targetCollection, String collectionsNameMask, int insertBatchSize = 100) { // Parallel Options var multiThreadingOptions = new ParallelOptions() { MaxDegreeOfParallelism = System.Environment.ProcessorCount * 2 }; // Multi-threading Processing of each copy request foreach (var collectionName in sourceDatabase.GetCollectionNames().Where(t => t.Contains(collectionsNameMask))) { // Console Feedback Console.WriteLine("Merging Collection : " + collectionName); SharedMethods.CopyCollection(sourceDatabase, targetDatabase, collectionName, targetCollection, insertBatchSize); } }
static IEnumerable <Tuple <string, string> > ListCollections(MongoDatabase sourceServer, List <string> collections, string targetCollection) { // Forcing targetcollection to be null if it's empty if (targetCollection == "") { targetCollection = null; } if (collections == null || collections.Count == 0) { foreach (var c in sourceServer.GetCollectionNames()) { yield return(Tuple.Create(c, c)); } } else { var list = sourceServer.GetCollectionNames().ToList(); var hashOrdinal = new HashSet <string> (list, StringComparer.Ordinal); foreach (var c in collections) { if (hashOrdinal.Contains(c)) { yield return(Tuple.Create(c, (targetCollection ?? c))); } else if (c.IndexOf('=') > 0) { var split = c.Split('='); var k = split[0]; var col = hashOrdinal.Contains(k) ? k : list.FirstOrDefault(name => k.Equals(name, StringComparison.OrdinalIgnoreCase)); if (!String.IsNullOrEmpty(col) && !String.IsNullOrEmpty(split[1])) { yield return(Tuple.Create(col, split[1])); } } else { foreach (var col in list.Where(name => SharedMethods.WildcardIsMatch(c, name, true))) { yield return(Tuple.Create(col, (targetCollection ?? c))); } } } } }
/// <summary> /// Duplicates all the collections whose name is on the List /// of collections received. /// </summary> /// <param name="database">Database name</param> /// <param name="collectionsToDuplicate">List of collections to be duplicated</param> /// <param name="insertBatchSize">Batch Insert size</param> /// <param name="copyIndexes">True if the indexes should be copied, false otherwise</param> /// <param name="duplicationSuffix">Suffix that wil be appended to the name of the collection, when duplicated</param> public static void CollectionsDuplicate(MongoDatabase database, Lazy <List <String> > collectionsToDuplicate, int insertBatchSize = 100, bool copyIndexes = true, string duplicationSuffix = "_COPY") { if (String.IsNullOrWhiteSpace(duplicationSuffix)) { throw new ArgumentNullException("duplicationSuffix"); } // Parallel Options var multiThreadingOptions = new ParallelOptions() { MaxDegreeOfParallelism = System.Environment.ProcessorCount * 2 }; // Multi-threading Processing of each duplicate request Parallel.ForEach(collectionsToDuplicate.Value, multiThreadingOptions, collectionName => { // Console Feedback Console.WriteLine("Duplicating Collection : " + collectionName); // Duplication Method SharedMethods.CopyCollection(database, database, collectionName, collectionName + duplicationSuffix, insertBatchSize, copyIndexes, true); }); }
/// <summary> /// Migrates data and indexes of all collections of a certain database, to another /// </summary> /// <param name="sourceDatabase">Source database - Where the data will come from</param> /// <param name="targetDatabase">Target database - Where the data will go to</param> /// <param name="collectionsNameMask">Mask that will be used to decide whether one collection will be copied or not - Case Sensitive</param> /// <param name="insertBatchSize">Size (in records) of the chunk of data that will be inserted per batch</param> /// <param name="copyIndexes">True if the indexes should be copied aswell, false otherwise</param> public static void CollectionsCopy(MongoDatabase sourceDatabase, MongoDatabase targetDatabase, String collectionsNameMask, int insertBatchSize = -1, bool copyIndexes = true, bool dropCollections = false, int threads = 1) { var collections = sourceDatabase.GetCollectionNames().Where(t => t.Contains(collectionsNameMask)); if (threads <= 1) { foreach (var collectionName in collections) { SharedMethods.CopyCollection(sourceDatabase, targetDatabase, collectionName, String.Empty, insertBatchSize, copyIndexes, dropCollections); } } else { // Multi-threading Processing of each copy request MongoToolsLib.SimpleHelpers.ParallelTasks <string> .Process(collections, 0, threads, collectionName => { // Console Feedback Console.WriteLine("Migrating Collection : " + collectionName); SharedMethods.CopyCollection(sourceDatabase, targetDatabase, collectionName, String.Empty, insertBatchSize, copyIndexes, dropCollections); }); } }
static IEnumerable <Tuple <MongoDatabase, MongoDatabase> > ListDatabases(MongoServer sourceServer, MongoServer targetServer, List <string> sourceDatabases, List <string> targetDatabases) { if (sourceDatabases == null) { yield break; } if (targetDatabases == null || targetDatabases.Count == 0) { targetDatabases = null; } // check if we are on the same server! bool sameServer = ServersAreEqual(sourceServer, targetServer); // prepare available databases list var databases = sourceServer.GetDatabaseNames().ToList(); var availableDatabases = new HashSet <string> (databases, StringComparer.Ordinal); // create mappings if (targetDatabases == null) { for (int i = 0; i < sourceDatabases.Count; i++) { string k = sourceDatabases[i]; if (k.IndexOf('=') > 0) { var split = k.Split('='); k = split[0]; var db = availableDatabases.Contains(k) ? k : databases.FirstOrDefault(name => k.Equals(name, StringComparison.OrdinalIgnoreCase)); // check if database was found if (String.IsNullOrEmpty(db) || String.IsNullOrEmpty(split[1])) { continue; } yield return(Tuple.Create(sourceServer.GetDatabase(db), targetServer.GetDatabase(split[1]))); } else { foreach (var db in databases.Where(name => SharedMethods.WildcardIsMatch(k, name, true))) { yield return(Tuple.Create(sourceServer.GetDatabase(db), targetServer.GetDatabase(db))); } } } } else { // match for (int i = 0; i < sourceDatabases.Count; i++) { string k = sourceDatabases[i]; var db = availableDatabases.Contains(k) ? k : databases.FirstOrDefault(name => k.Equals(name, StringComparison.OrdinalIgnoreCase)); // check if database was found if (String.IsNullOrEmpty(db) || String.IsNullOrEmpty(targetDatabases[i])) { continue; } yield return(Tuple.Create(sourceServer.GetDatabase(db), targetServer.GetDatabase(targetDatabases[i]))); } } }
static void CollectionCopy(CopyInfo item) { SharedMethods.CopyCollection(item.SourceDatabase, item.TargetDatabase, item.SourceCollection, item.TargetCollection, item.BatchSize, item.CopyIndexes, item.DropCollections, item.SkipCount, item.EraseObjectId, item.Options); }