Upserting in Mongo DB using official C# driver

Version 2 of the MongoDB C# driver requires setting the IsUpsert flag in the write commands. This example will upsert an entire document.

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);

Version 1 of the MongoDB C# driver implements this logic within the Save command.

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };

The Save method is a combination of Insert and Update. If the Id member of the document has a value, then it is assumed to be an existing document and Save calls Update on the document (setting the Upsert flag just in case it actually is a new document after all). Otherwise it is assumed to be a new document and Save calls Insert after first assigning a newly generated unique value to the Id member.


Note: This does require the proper mapping of the Id field however. More info on that here:

Starting from v2.0 of the driver there's a new async-only API. The old API should no longer be used as it's a blocking facade over the new API and is deprecated.

The currently recommended way to upsert a document is by calling and awaiting ReplaceOneAsync with the IsUpsert flag turned on and a filter that matches the relevant document:

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

You can check whether the operation was an insert or an update by looking at ReplaceOneResult.MatchedCount:

The following code is from a working app:

    Query.EQ("weekNumber", week),

The weekplanStore is my MongoDB collection, and the code will update the document found with the query in the first argument or insert a new one if none is found. The "trick" is to use the UpdateFlags.Upsert modifier.

The rawWeekPlan is the object inserted or updated, and has the following type:

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

and turned into bson by the driver automatically.