Mongodbの公式ドキュメントでは、upsertsに言及しているため、次の代わりにupsertコマンドを記述することは本当に素晴らしいことです。
if (_campaignRepo.Exists(camp))
{
_campaignRepo.DeleteByIdAndSystemId(camp);
}
_campaignRepo.Save(camp);
可能であれば、dbレベルでそのロジックを実装するもの。では、アップサートがある場合、それを行う方法は何ですか?
次のコードは、動作中のアプリからのものです。
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に変わりました。
MongoDB C#ドライバーのバージョン2では、書き込みコマンドで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);
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
:
通常の更新コマンドを使用できますが、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);
そのコードは動作しているアプリケーションから適応されています(わかりやすくするために短縮されています)