在mongodb的官方文档中,他们提到了upserts,所以编写upsert命令代替以下内容真的很好:
if (_campaignRepo.Exists(camp))
{
_campaignRepo.DeleteByIdAndSystemId(camp);
}
_campaignRepo.Save(camp);
如果可能的话,可以在db级别实现该逻辑的东西。那么如果有一个upsert的方法是什么呢?
答案 0 :(得分:52)
版本2 需要在write命令中设置IsUpsert
标志。此示例将插入整个文档。
var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
var result = await collection.ReplaceOneAsync(
filter: new BsonDocument("_id", 123),
options: new UpdateOptions { IsUpsert = true },
replacement: newDoc);
版本1 在Save
命令中实现此逻辑。
var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
collection.Save(newDoc);
Save方法是Insert和Update的组合。如果文档的Id成员有值,则假定它是现有文档并保存调用文档上的Update(设置Upsert标志,以防万一它实际上是一个新文件)。否则,在首先将新生成的唯一值分配给Id成员后,它将被假定为新文档并保存调用插入。
参考: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
答案 1 :(得分:30)
以下代码来自正在运行的应用:
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。
答案 2 :(得分:30)
从驱动程序的v2.0开始,有一个新的async-only API。不应再使用旧的API,因为它是新API的阻止外观,不推荐使用。
目前推荐的备份文档的方法是调用{等待ReplaceOneAsync
并打开IsUpsert
标记,并使用与相关文档匹配的过滤器:
Hamster hamster = ...
var replaceOneResult = await collection.ReplaceOneAsync(
doc => doc.Id == hamster.Id,
hamster,
new UpdateOptions {IsUpsert = true});
您可以通过查看ReplaceOneResult.MatchedCount
:
答案 3 :(得分:4)
您可以使用常规更新命令,但只需将其传递给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);
该代码改编自工作应用程序(为清晰起见缩短)