Exemplo n.º 1
0
        private static void CreateIndexes(MongoCollection <BsonDocument> sourceCollection, MongoCollection <BsonDocument> targetCollection, FlexibleOptions options)
        {
            if (options == null)
            {
                options = new FlexibleOptions();
            }
            var logger = NLog.LogManager.GetLogger("CreateIndexes");

            logger.Debug("{2} - {0}.{1} - Start index creation", sourceCollection.Database.Name, sourceCollection.Name, Thread.CurrentThread.ManagedThreadId);

            var command = new CommandDocument();

            command.Add("createIndexes", targetCollection.Name);
            var indexList = new BsonArray();

            command.Add("indexes", indexList);

            // Copying Indexes - If Any
            foreach (IndexInfo idx in sourceCollection.GetIndexes().ToList())
            {
                // Skipping "_id_" default index - Since Every mongodb Collection has it
                if (idx.Name == "_id_")
                {
                    continue;
                }

                // Recreating Index Options based on the current index options
                var opts = IndexOptions.SetBackground(idx.IsBackground || options.Get("indexes-background", false))
                           .SetSparse(idx.IsSparse || options.Get("indexes-sparse", false))
                           .SetUnique(idx.IsUnique).SetName(idx.Name).SetDropDups(idx.DroppedDups);

                if (idx.TimeToLive < TimeSpan.MaxValue)
                {
                    opts.SetTimeToLive(idx.TimeToLive);
                }

                // Adding Index
                try
                {
                    if (targetCollection.Database.Server.BuildInfo.Version.Major < 2 && targetCollection.Database.Server.BuildInfo.Version.MajorRevision < 6)
                    {
                        logger.Debug("{2} - {0}.{1} - Creating index: {2}", sourceCollection.Database.Name, sourceCollection, idx.Name, Thread.CurrentThread.ManagedThreadId);
                        targetCollection.CreateIndex(idx.Key, opts);
                    }
                    else
                    {
                        logger.Debug("{2} - {0}.{1} - Prepare index creation: {2}", sourceCollection.Database.Name, sourceCollection, idx.Name, Thread.CurrentThread.ManagedThreadId);
                        // removes the namespace to allow mongodb to generate the correct one...
                        var doc = idx.RawDocument;
                        doc.Remove("ns");
                        if (options.Get("indexes-background", false))
                        {
                            doc["background"] = true;
                        }
                        if (options.Get("indexes-sparse", false))
                        {
                            doc["sparse"] = true;
                        }
                        indexList.Add(doc);
                    }
                }
                catch (Exception ex)
                {
                    // check for timeout exception that may occur if the collection is large...
                    if (ex is System.IO.IOException || ex is System.Net.Sockets.SocketException || (ex.InnerException != null && ex.InnerException is System.Net.Sockets.SocketException))
                    {
                        logger.Warn("{3} - {0}.{1} - Timeout creating index {2}, this may occur in large collections. You should check manually after a while.", sourceCollection.Database.Name, sourceCollection.Name, idx.Name, Thread.CurrentThread.ManagedThreadId);
                        // wait for index creation....
                        for (var i = 0; i < 30; i++)
                        {
                            System.Threading.Thread.Sleep(10000);
                            try
                            {
                                if (targetCollection.IndexExists(idx.Name))
                                {
                                    break;
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                    else
                    {
                        logger.Error(ex, "{0}.{1} - Error creating index {2}" + idx.Name);
                    }

                    logger.Warn("{3} - {0}.{1} - Index details: {2}", sourceCollection.Database.Name, sourceCollection.Name, idx.RawDocument.ToJson(), Thread.CurrentThread.ManagedThreadId);
                }
            }

            if (indexList.Count > 0)
            {
                try
                {
                    logger.Debug("{3} - {0}.{1} - Creating {2} indexes", sourceCollection.Database.Name, sourceCollection, indexList.Count, Thread.CurrentThread.ManagedThreadId);
                    targetCollection.Database.RunCommand(command);
                }
                catch (Exception ex)
                {
                    // check for timeout exception that may occur if the collection is large...
                    if (ex is System.IO.IOException || ex is System.Net.Sockets.SocketException || (ex.InnerException != null && ex.InnerException is System.Net.Sockets.SocketException))
                    {
                        logger.Warn("{3} - {0}.{1} - Timeout creating {2} indexes, this may occur in large collections. You should check manually after a while.", sourceCollection.Database.Name, sourceCollection.Name, indexList.Count, Thread.CurrentThread.ManagedThreadId);
                        logger.Warn("{3} - {0}.{1} - Index details: {2}", sourceCollection.Database.Name, sourceCollection.Name, command.ToJson(), Thread.CurrentThread.ManagedThreadId);
                    }
                    else
                    {
                        logger.Error(ex, "{2} - {0}.{1} - Error creating indexes", sourceCollection.Database.Name, sourceCollection.Name, Thread.CurrentThread.ManagedThreadId);
                        logger.Error("{3} - {0}.{1} - Index details: {2}", sourceCollection.Database.Name, sourceCollection.Name, command.ToJson(), Thread.CurrentThread.ManagedThreadId);
                    }
                }
            }

            logger.Debug("{2} - {0}.{1} - Index creation completed", sourceCollection.Database.Name, sourceCollection, Thread.CurrentThread.ManagedThreadId);
        }