Загрузка в БД Mongo с использованием официального драйвера C # - PullRequest
36 голосов
/ 30 августа 2011

В официальной документации mongodb они упоминают upserts, поэтому было бы неплохо написать команду upsert вместо:

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

_campaignRepo.Save(camp);

что-то, что реализовало бы эту логику на уровне БД, если это возможно,Так как же сделать упсерт, если он есть?

Ответы [ 4 ]

54 голосов
/ 30 августа 2011

Версия 2 драйвера MongoDB C # требует установки флага 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);

Версия 1 драйвера MongoDB C # реализует эту логику в команде Save.

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

Метод Save представляет собой комбинацию вставки и обновления. Если элемент Id документа имеет значение, то он считается существующим документом иСохранение звонков Обновление документа (установка флага Upsert на тот случай, если он действительно новый документ).В противном случае предполагается, что это новый документ и сохраняются вызовы Insert после первого присвоения вновь сгенерированного уникального значения члену Id.

Ссылка: 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

31 голосов
/ 16 мая 2015

Начиная с версии 2.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:

31 голосов
/ 30 августа 2011

Следующий код взят из работающего приложения:

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автоматически.

4 голосов
/ 30 августа 2011

Вы можете использовать обычную команду обновления, но просто передать ей флаг обновления 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);

Этот код взят из рабочего приложения (сокращено для ясности)

...