Коллекция MongoDB С#. Сохранить или вставить + обновить

Из документации С#:

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

Я создаю свои идентификаторы вручную в базовом классе, от которого наследуются все объекты моего домена. Таким образом, все объекты моего домена имеют идентификатор, когда они вставляются в MongoDB.

Вопрос в том, должен ли я использовать collection.Save и сохранять простой интерфейс, или это на самом деле приводит к некоторым накладным расходам в вызове сохранения (с флагом Upsert), и должен ли я использовать вместо этого collection.Insert и Update?

Я думаю, что метод Save сначала вызывает Update, а затем выясняет, что моего нового объекта вообще не существует, и вместо этого вызывает Insert. Я ошибся? Кто-нибудь проверял это?

Примечание. Я вставляю массовые данные с помощью InsertBatch, поэтому в этом случае большие фрагменты данных не будут иметь значения.

Изменить, принять меры

Я написал небольшой тест, чтобы выяснить, имеет ли вызов Update с флагом Upsert некоторые накладные расходы, поэтому Insert может быть лучше. Оказалось, что они бегают с одинаковой скоростью. См. мой тестовый код ниже. MongoDbServer и IMongoDbServer — это мой собственный общий интерфейс для изоляции хранилища.

IMongoDbServer server = new MongoDbServer();
Stopwatch sw = new Stopwatch();
long d1 = 0;
long d2 = 0;
for (int w = 0; w <= 100; w++)
{
    sw.Restart();
    for (int i = 0; i <= 10000; i++)
    {
        ProductionArea area = new ProductionArea();
        server.Save(area);
    }
    sw.Stop();
    d1 += sw.ElapsedMilliseconds;
    sw.Restart();
    for (int i = 0; i <= 10000; i++)
    {
        ProductionArea area = new ProductionArea();
        server.Insert(area);
    }
    sw.Stop();
    d2 += sw.ElapsedMilliseconds;
}
long a1 = d1/100;
long a2 = d2/100;

person Paw Baltzersen    schedule 21.11.2011    source источник


Ответы (1)


Метод Save не совершает два обращения к серверу.

Эвристика такова: если сохраняемый документ не имеет значения для поля _id, то для него генерируется значение и затем вызывается Insert. Если сохраняемый документ имеет ненулевое значение для _id, то Update вызывается с флагом Upsert, и в этом случае сервер должен решить, выполнять ли вставку или обновление.

Я не знаю, дороже ли Upsert, чем Insert. Я подозреваю, что они почти одинаковы, и что действительно важно, так это то, что в любом случае это односетевое путешествие туда и обратно.

Если вы знаете, что это новый документ, вы также можете вызвать Insert. И вызов InsertBatch намного более эффективен, чем вызов множества отдельных вставок. Так что определенно предпочтите InsertBatch для сохранения.

person Robert Stam    schedule 21.11.2011