【问题标题】:InsertMany() gives FormatException, my attempt at handling it results in duplicate key errorInsertMany() 给出 FormatException,我尝试处理它会导致重复键错误
【发布时间】:2018-08-02 16:19:30
【问题描述】:

我有一个函数可以将条目列表插入到我的 MongoDB 数据库中,如下所示:

public static void TraceDatabaseInsert(string collection, List<BsonDocument> posts)
    {
        var connectionString = "mongodb://localhost:27017";

        var client = new MongoClient(connectionString);

        IMongoDatabase db = client.GetDatabase("TraceDatabase");

        var coll = db.GetCollection<BsonDocument>(collection);

        try
        {
            coll.InsertMany(posts);
        }
        catch (FormatException)
        {
            if (posts.Count == 1)
            {
                Console.WriteLine("Error: Trace to large to enter into database");
            }
            else
            {
                var postsList = SplitList(posts);
                foreach (var entries in postsList)
                {
                    coll.InsertMany(entries);
                }
            }
        }


    }

在极少数情况下,帖子太大而无法一次性插入并引发 FormatException,因此创建了一个将帖子一分为二的函数:

public static List<List<BsonDocument>> SplitList(List<BsonDocument> list)
    {
        var firstHalf = (int)Math.Ceiling(list.Count / 2.0);
        var secondHalf = list.Count - firstHalf;
        var returnList = new List<List<BsonDocument>>();
        returnList.Add(list.GetRange(0, firstHalf));
        returnList.Add(list.GetRange(firstHalf, secondHalf));

        return returnList;
    }

但是,当我尝试插入拆分列表时,我收到了 E11000 重复键错误形式的 MongoBulkWriteException。

这是由于初始操作在抛出异常之前插入了一些文档,所以我实际上是在尝试插入重复项吗?有谁知道解决这个问题的方法吗?

否则,可能是什么原因?

编辑:Here's an image of the local variables at the time of the exception being thrown

【问题讨论】:

  • posts.Count 在本例中为 189,新列表分别包含 95 和 94 个帖子。

标签: c# .net mongodb mongodb-.net-driver


【解决方案1】:

几乎可以肯定的是,对InsertMany 的第一次调用是插入一些 记录。根据the docs

注意插入了一个文档:_id的第一个文档:13 将插入成功,但第二次插入将失败。这将 还阻止插入队列中剩余的其他文档。

然后您尝试再次将它们全部插入(在catch 内)。然后这会失败,因为其中 一些 被插入到第一个 InsertMany 调用中。

您可能需要考虑使用transactions。或者,当您在 cmets 中突出显示时,将 Ordered 设置为 false 以便:

排除 Write Concern 错误,有序操作在一个 错误,而无序操作继续处理任何 队列中剩余的写操作。

【讨论】:

  • 从文档中,看起来我可以将“Ordered”设置为 false 并且它只会跳过重复的文档。您认为这可能会导致意外问题吗?
  • 似乎有效,但它确实表明我对由于尺寸导致插入失败的初始问题的“解决方案”没有得到修复。所以这需要更多的调试。不过,感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2021-03-17
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多