web-dev-qa-db-fra.com

Insertion dans Mongodb à l'aide du pilote C # officiel

Dans la documentation officielle de mongodb, ils mentionnent upserts, donc ce serait vraiment bien d'écrire une commande upsert au lieu de:

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

_campaignRepo.Save(camp);

quelque chose qui implémenterait cette logique au niveau de la base de données si cela est possible. Alors, quelle est la façon de faire un upsert s'il y en a un?

37
Yurii Hohan

Le code suivant provient d'une application qui fonctionne:

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

Le weekplanStore est ma collection MongoDB, et le code mettra à jour le document trouvé avec la requête dans le premier argument ou en insérera un nouveau si aucun n'est trouvé. L'astuce consiste à utiliser le modificateur UpdateFlags.Upsert.

Le rawWeekPlan est l'objet inséré ou mis à jour et a le type suivant:

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

et transformé en bson par le conducteur automatiquement.

32
Christian Horsdal

La version 2 du pilote MongoDB C # nécessite la définition de l'indicateur IsUpsert dans les commandes d'écriture. Cet exemple mettra un document entier à l'envers.

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

La version 1 du pilote MongoDB C # implémente cette logique dans la commande Save.

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
collection.Save(newDoc);

La méthode Save est une combinaison d'insertion et de mise à jour. Si le membre Id du document a une valeur, il est supposé qu'il s'agit d'un document existant et Save appelle Update sur le document (définition de la Indicateur Upsert juste au cas où il s'agirait en fait d'un nouveau document). Sinon, il est supposé être un nouveau document et Enregistrer les appels Insérer après avoir d'abord attribué une valeur unique nouvellement générée au membre Id.

Référence: http://mongodb.github.io/mongo-csharp-driver/1.11/driver/#save-tdocument-method

Remarque: Cela nécessite cependant le mappage correct du champ Id. Plus d'informations à ce sujet ici: http://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#identifying-the-id-field-or-property

57
Mani Gandham

À partir de la version 2.0 du pilote, il existe une nouvelle API uniquement asynchrone. L'ancienne API ne devrait plus être utilisée car elle constitue une façade de blocage sur la nouvelle API et est obsolète.

La méthode actuellement recommandée pour insérer un document consiste à appeler et à attendre ReplaceOneAsync avec le drapeau IsUpsert activé et un filtre qui correspond au document pertinent:

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

Vous pouvez vérifier si l'opération était une insertion ou une mise à jour en consultant ReplaceOneResult.MatchedCount:

32
i3arnon

Vous pouvez utiliser la commande de mise à jour régulière, mais passez-lui simplement le drapeau de mise à jour 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);

Ce code est adapté d'une application de travail (raccourci pour plus de clarté)

4
jeffsaracco