Upserting in Mongo DB using official C# driver

后端 未结 4 744
别跟我提以往
别跟我提以往 2020-12-04 18:04

In the official documentation of mongodb they mention upserts, so it would be really nice to write an upsert command instead of:

if (_campaignRepo.Exists(cam         


        
相关标签:
4条回答
  • 2020-12-04 18:14

    You can use the regular update command, but just pass it the Upsert update flag

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

    That code is adapted from a working application (shortened for clarity)

    0 讨论(0)
  • 2020-12-04 18:17

    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" } };
    collection.Save(newDoc);
    

    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.

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

    Note: This does require the proper mapping of the Id field however. More info on that here: http://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#identifying-the-id-field-or-property

    0 讨论(0)
  • 2020-12-04 18:18

    The following code is from a working app:

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

    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.

    0 讨论(0)
  • 2020-12-04 18:37

    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, 
        hamster, 
        new UpdateOptions {IsUpsert = true});
    

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

    0 讨论(0)
提交回复
热议问题