Нулевое значение не может быть записано в корневой уровень документа BSON - PullRequest
0 голосов
/ 06 февраля 2019

Когда я пытался вставить список записей адресных строк, скажем, около 9 000 000 в коллекцию mongodb в одном методе insertManyAsync, я получил сообщение об ошибке Нулевое значение не может быть записано на корневой уровень документа BSON.

Проверили, есть ли в списке пустые записи, но не смогли найти.Эта ошибка, кажется, недоступна, когда я пытался найти ее.

                Parallel.For(0, addresslines.Count, async index =>
                {
                    tempAddresses.Add(new TempAddress() {  AddressLine1 = addresslines["AddressLine1"], Village = addresslines["Village"] });

                });

                /* Foreach without parallel works.
                foreach (var item in pincodestrings)
                {
                    tempAddresses.Add(new TempAddress() { AddressLine1 = DateTime.Now.ToLongDateString() }); //, AddressLine2 = "sample2", Dist_City = "sample", Pincode = 1, State = "yy", Town_Taluk = "aa", Village = "vv" });

                }*/

                if (tempAddresses.Count > 0)
                {
                   await _context.QCSubmission.InsertManyAsync(tempAddresses.AsEnumerable(), null);
                }

Пробовал с несколькими записями сказать 100 записей, что работает нормально.В чем заключалась проблема вставки массовых записей в MongoDB.Нужно ли проверять и исправлять в MongoDB?

ОБНОВЛЕНИЕ: Согласно комментариям, заменили Parallel.Foreach на for-each, который работает, но для обработки огромных данных использование Parallel обязательно ускоряется.

1 Ответ

0 голосов
/ 06 февраля 2019

Проблема, по-видимому, заключается в многопоточном доступе к не поточнобезопасной коллекции из System.Collection.Generic, которая при одновременном добавлении значений к нему в нескольких потоках может привести к отсутствующим значениям или нулевым значениям.в коллекцию или отсоединение ее фрагментов и другого неопределенного поведения.

Вместо этого можно использовать одну из потоковобезопасных коллекций из System.Collections.Concurrent, в этом случае, вероятно, ConcurrentBag<TempAddress>.

Редактировать:

Я сделал короткий тест для сравнения производительности блокировок и потоковобезопасных коллекций в параллельном режиме с использованием нормального цикла for и записи в стандартную универсальную коллекцию.Возможно, вы захотите сделать аналогичный тест с вашими данными и посмотреть, как они сравниваются.Я запустил это на DotNet fiddle , и он предположил, что использование обычного списка может быть быстрее.

Однако чем больше вы делаете, чем записываете в коллекцию в цикле, тем лучше будет параллелизм.

using System;
using System.Diagnostics;

public static class Module1
{
    public static void Main()
    {
        System.Collections.Concurrent.ConcurrentBag<int> bag = new System.Collections.Concurrent.ConcurrentBag<int>();
        // Test Bag Parallel
        Stopwatch t = Stopwatch.StartNew();
        System.Threading.Tasks.Parallel.For(0, 500000, index =>
        {
            bag.Add(index);
        });
        t.Stop();
        Console.WriteLine("Parallel Bag test completed in " + t.ElapsedTicks.ToString());
        // Test Bag Incremental
        bag = new System.Collections.Concurrent.ConcurrentBag<int>();
        t = Stopwatch.StartNew();
        for (int index = 0; index <= 500000; index += 1)
        {
            bag.Add(index);
        }
        t.Stop();
        Console.WriteLine("Incremental Bag test completed in " + t.ElapsedTicks.ToString());
        bag = null;
        // Test List Incremental
        t = Stopwatch.StartNew();
        System.Collections.Generic.List<int> lst = new System.Collections.Generic.List<int>();
        t = Stopwatch.StartNew();
        for (int index = 0; index <= 500000; index += 1)
        {
            lst.Add(index);
        }
        t.Stop();
        Console.WriteLine("Incremental list test completed in " + t.ElapsedTicks.ToString());
    }
}

Выход:

Тест параллельной сумки завершен в 229264
Тест добавочной сумки завершен в 1115224
Тест добавочной таблицы завершен в 42385

...