C# mongodb 驱动程序 2.0 - 如何在批量操作中更新插入

本文关键字:批量操作 更新 插入 驱动程序 mongodb | 更新日期: 2023-09-27 18:36:34

我从 1.9 迁移到 2.2 并阅读文档,我惊讶地发现在批量操作期间无法再更新插入,因为操作不允许选项。

bulkOps.Add(new UpdateOneModel<BsonDocument>(filter, update));
collection.BulkWrite(bulkOps);

应该是

options.isUpsert = true;
bulkOps.Add(new UpdateOneModel<BsonDocument>(filter, update, options));
collection.BulkWrite(bulkOps);

这项工作正在进行中,有意的,还是我错过了什么?谢谢。

C# mongodb 驱动程序 2.0 - 如何在批量操作中更新插入

UpdateOneModelIsUpsert 属性设置为 true 以将更新转换为更新插入。

var bulkOps = new List<WriteModel<BsonDocument>>();
// Create and add one or more write models to list
var upsertOne = new UpdateOneModel<BsonDocument>(filter, update) { IsUpsert = true };
bulkOps.Add(upsertOne);
// Write all changes as a batch
collection.BulkWrite(bulkOps);

给定的 mongo 集合

IMongoCollection<T> collection

以及要插入的记录的枚举,其中 T 具有 Id 字段。

IEnumerable<T> records 

此代码段将执行批量更新插入(过滤条件可能会根据情况更改):

var bulkOps = new List<WriteModel<T>>();
foreach (var record in records)
{
    var upsertOne = new ReplaceOneModel<T>(
        Builders<T>.Filter.Where(x => x.Id == record.Id),
        record)
    { IsUpsert = true };
    bulkOps.Add(upsertOne);
}
collection.BulkWrite(bulkOps);

这是一个基于@Aviko响应的扩展方法

public static BulkWriteResult<T> BulkUpsert<T>(this IMongoCollection<T> collection, IEnumerable<T> records)
    {
        string keyname = "_id";
        #region Get Primary Key Name 
        PropertyInfo[] props = typeof(T).GetProperties();
        foreach (PropertyInfo prop in props)
        {
            object[] attrs = prop.GetCustomAttributes(true);
            foreach (object attr in attrs)
            {
                BsonIdAttribute authAttr = attr as BsonIdAttribute;
                if (authAttr != null)
                {
                    keyname = prop.Name;
                }
            }
        }
        #endregion
        var bulkOps = new List<WriteModel<T>>();

        foreach (var entry in records)
        {
            var filter = Builders<T>.Filter.Eq(keyname, entry.GetType().GetProperty(keyname).GetValue(entry, null));
            var upsertOne = new ReplaceOneModel<T>(filter, entry){ IsUpsert = true };
            bulkOps.Add(upsertOne);
        }
        return collection.BulkWrite(bulkOps);
    }