您可以使用Upsert进行此操作:
var coll = _mongoCollection.getCollection<ModelClass>("collectionName");
var model = new ModelClass()
{
Name = A,
Type = B,
Contact = C,
Field4 = "F4",
Field5 = "F5",
};
await coll.ReplaceOneAsync(s => s.Name == model.Name
&& s.Type == model.Type
&& s.Contact == model.Contact,
model,
new ReplaceOptions() { IsUpsert = true });
上述代码判断是否存在匹配的文档;如果是,则将其替换,否则将插入新文档.如果方法不是async
或UpdateOne(Async)
,也可以使用ReplaceOne
来更细粒度地更新现有文档.
更新后插入
例如,如果只想在没有文档的情况下插入新文档,可以使用以下不替换文档的upsert:
var coll = _mongoCollection.getCollection<ModelClass>("collectionName");
var model = new ModelClass()
{
Name = A,
Type = B,
Contact = C,
Field4 = "F4",
Field5 = "F5",
};
var update = Builders<ModelClass>.Update
.SetOnInsert(x => x.Field4, model.Field4)
.SetOnInsert(x => x.Field5, model.Field5);
var result = await coll.UpdateOneAsync(
x => x.Name == model.Name && x.Type == model.Type && x.Contact == model.Contact,
update,
new UpdateOptions() { IsUpsert = true });
如果还不存在任何文档,则上述代码将创建一个新文档.如果插入了文档,则可以选中result.UpsertedId
.如果为空,则表示未插入任何文档,否则它包含插入文档的id.
更新仅对其余两个字段使用SetOnInsert
个操作.如果文档已存在,则保持不变.
批量升级并更新
如果要使用批量操作执行多个upserts,可以使用以下代码:
var update = Builders<ModelClass>.Update
.SetOnInsert(x => x.Field4, model.Field4)
.SetOnInsert(x => x.Field5, model.Field5);
var bldr = Builders<ModelClass>.Filter;
var updates = new List<WriteModel<ModelClass>>();
var updateOneModel = new UpdateOneModel<ModelClass>(
bldr.Eq(x => x.Name, model.Name) & bldr.Eq(x => x.Type, model.Type) & bldr.Eq(x => x.Contact, model.Contact),
update);
updateOneModel.IsUpsert = true;
updates.Add(updateOneModel);
// ... add additional UpdateModels
var result = await coll.BulkWriteAsync(updates);
在这种情况下,result包含一个upserted id的列表;还有一个Index
属性,您可以使用它来找出哪些UpdateModels
导致了向上插入,哪些没有.