繁体   English   中英

使用官方 C# 驱动程序在 Mongo DB 中更新

[英]Upserting in Mongo DB using official C# driver

在 mongodb 的官方文档中他们提到了 upserts,所以写一个 upsert 命令而不是:

if (_campaignRepo.Exists(camp))
{
    _campaignRepo.DeleteByIdAndSystemId(camp);
}

_campaignRepo.Save(camp);

如果可能的话,可以在数据库级别实现该逻辑的东西。 那么如果有一个 upsert,有什么方法呢?

MongoDB C# 驱动程序的版本 2需要在写入命令中设置IsUpsert标志。 此示例将插入整个文档。

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
var result = await collection.ReplaceOneAsync(
                filter: new BsonDocument("_id", 123),
                options: new ReplaceOptions { IsUpsert = true },
                replacement: newDoc);

MongoDB C# 驱动程序的第 1 版Save命令中实现了此逻辑。

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
collection.Save(newDoc);

Save 方法是 Insert 和 Update 的组合。 如果文档的 Id 成员有一个值,则假定它是一个现有文档,并且 Save 调用该文档的 Update(设置 Upsert 标志以防它实际上是一个新文档)。 否则,它被假定为一个新文档,并且 Save 在第一次将新生成的唯一值分配给 Id 成员后调用 Insert。

参考: http : //mongodb.github.io/mongo-csharp-driver/1.11/driver/#save-tdocument-method

注意:这确实需要正确映射 Id 字段。 更多信息在这里: http : //mongodb.github.io/mongo-csharp-driver/1.11/serialization/#identifying-the-id-field-or-property

从驱动程序的 v2.0 开始,有一个新的仅异步 API。 不应再使用旧 API,因为它是新 API 的阻塞外观,已弃用。

当前推荐的插入文档的方法是调用并等待ReplaceOneAsync并打开IsUpsert标志和匹配相关文档的过滤器:

Hamster hamster = ...
var replaceOneResult = await collection.ReplaceOneAsync(
    doc => doc.Id == hamster.Id, 
    hamster, 
    new UpdateOptions {IsUpsert = true});

您可以通过查看ReplaceOneResult.MatchedCount来检查操作是插入还是更新:

以下代码来自一个工作应用程序:

weekplanStore.Update(
    Query.EQ("weekNumber", week),
    Update.Replace(rawWeekPlan),
    UpdateFlags.Upsert);

weekplanStore 是我的 MongoDB 集合,代码将更新在第一个参数中使用查询找到的文档,或者如果没有找到则插入一个新文档。 “技巧”是使用 UpdateFlags.Upsert 修饰符。

rawWeekPlan 是插入或更新的对象,具有以下类型:

private class RawWeekPlan
{
    public ObjectId id;
    public int weekNumber;
    public WeekPlanEntry[] entries;
}

并被驱动自动变成bson。

您可以使用常规更新命令,但只需将 Upsert 更新标志传递给它

MongoCollection collection = db.GetCollection("matches");
var query = new QueryDocument("recordId", recordId);

var update = Update.Set("FirstName", "John").Set("LastName","Doe");
matchCollection.Update(query, update, UpdateFlags.Upsert, SafeMode.False);

该代码改编自一个工作应用程序(为了清楚起见缩短了)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM