C# mongodb driver 2.0 - 如何在批量操作中更新插入?
Posted
技术标签:
【中文标题】C# mongodb driver 2.0 - 如何在批量操作中更新插入?【英文标题】:C# mongodb driver 2.0 - How to upsert in a bulk operation? 【发布时间】: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);
这项工作是在进行中、有意为之,还是我遗漏了什么?谢谢。
【问题讨论】:
【参考方案1】:将 UpdateOneModel
的 IsUpsert
属性设置为 true 以将更新转换为 upsert。
var upsertOne = new UpdateOneModel<BsonDocument>(filter, update) IsUpsert = true ;
bulkOps.Add(upsertOne);
collection.BulkWrite(bulkOps);
【讨论】:
这应该添加到文档中。谢谢!! 什么是bulkOps?如何获得? @gyozokudor bulkOps 是List<WriteModel<T>>
我应该在filter
和update
变量中加入什么?【参考方案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);
【讨论】:
以上是关于C# mongodb driver 2.0 - 如何在批量操作中更新插入?的主要内容,如果未能解决你的问题,请参考以下文章
使用 MongoDB Driver for C# 的不同查询比通过 MongoDB shell 发送的相同查询慢得多