【问题标题】:C# mongodb driver 2.0 - How to upsert in a bulk operation?C# mongodb driver 2.0 - 如何在批量操作中更新插入?
【发布时间】:2016-06-11 18:41:45
【问题描述】:

我从 1.9 迁移到 2.2,reading the documentation 我惊讶地发现在批量操作期间无法再插入,因为操作不允许选项。

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 batch-processing mongodb-.net-driver bulk


    【解决方案1】:

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

    var upsertOne = new UpdateOneModel<BsonDocument>(filter, update) { IsUpsert = true };
    bulkOps.Add(upsertOne);
    collection.BulkWrite(bulkOps);
    

    【讨论】:

    • 这应该添加到文档中。谢谢!!
    • 什么是bulkOps?如何获得?
    • @gyozokudor bulkOps 是 List&lt;WriteModel&lt;T&gt;&gt;
    • 我应该在filterupdate变量中加入什么?
    【解决方案2】:

    给定 mongo 集合

    IMongoCollection<T> collection
    

    在 T 有 Id 字段的地方插入可枚举的记录。

    IEnumerable<T> records 
    

    这个sn-p会做一个bulk upsert(过滤条件可能会根据情况改变):

    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);
    

    【讨论】:

    • 我喜欢这种方法,但“记录”中的每个“记录”是否都必须包含一个 _Id 值?我的记录来源不包括 _Id 字段。所以我需要使用备用唯一键定位单个记录,例如尤基。当我使用 x.ukey == record.ukey 时,更新失败,因为 record._Id 字段全为零。有没有一种好方法可以在一个 upsert 中执行此操作,还是我必须获取目标记录以便在执行 upsert 之前设置 _Id 列?
    • 看到Replace后犹豫是否要使用。所以使用 UpdateOneModel 太慢了。刚刚又来了,检查一下,砰!太快了。
    • ????? :) tnx
    【解决方案3】:

    这里是基于@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);
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2015-11-08
      • 2014-10-06
      相关资源
      最近更新 更多