web-dev-qa-db-ja.com

公式のC#ドライバーを使用してMongodbに挿入する

Mongodbの公式ドキュメントでは、upsertsに言及しているため、次の代わりにupsertコマンドを記述することは本当に素晴らしいことです。

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

_campaignRepo.Save(camp);

可能であれば、dbレベルでそのロジックを実装するもの。では、アップサートがある場合、それを行う方法は何ですか?

37
Yurii Hohan

次のコードは、動作中のアプリからのものです。

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に変わりました。

32

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

57
Mani Gandham

ドライバーの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

32
i3arnon

通常の更新コマンドを使用できますが、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);

そのコードは動作しているアプリケーションから適応されています(わかりやすくするために短縮されています)

4
jeffsaracco