2014-01-27 1 views
0

Рассмотрим гипотетический фрагмент:MongoDB - Вставка результата запроса в одном редиректа

using (mongo.RequestStart(db)) 
{ 
    var collection = db.GetCollection<BsonDocument>("test"); 

    var insertDoc = new BsonDocument { { "currentCount", collection.Count() } }; 
    WriteConcernResult wcr = collection.Insert(insertDoc); 
} 

Он вставляет новый документ с «CURRENTCOUNT» установлен в значение, возвращенное collection.Count().

Это подразумевает два круглых поездки на сервер. Один для расчета collection.Count() и один для выполнения вставки. Есть ли способ сделать это в одном кругосветном путешествии?

Другими словами, может ли значение, присвоенное «currentCount», рассчитываться на сервере во время вставки?

Спасибо!

+0

Это только 1 вызов вместо 2. Это не большая разница. Я не думаю, что вы можете это сделать. – i3arnon

ответ

1

В настоящее время нет возможности сделать это (Mongo 2.4).

Предстоящая версия 2.6 должна иметь поддержку пакетных операций, но я не знаю, будет ли она поддерживать операции дозирования разных типов и использовать результаты одной операции из другой операции.

Что вы можете сделать, однако, выполнить эту логику на сервере, выразив его в JavaScript и использование eval:

collection.Database.Eval(new BsonJavaScript(@" 
    var count = db.test.count(); 
    db.test.insert({ currentCount: count }); 
"); 

Но это не рекомендуется, из-за нескольких причин: вы теряете беспокойство записи , он очень опасен с точки зрения безопасности, он требует прав администратора, он содержит глобальную блокировку записи, и он не будет работать с осколками кластеров :)

Я думаю, что ваш лучший маршрут на данный момент должен был бы сделать это в двух запросах. Если вы ищете атомные обновления или счетчики (которые точно не соответствуют вашему примеру, но кажутся несколько связанными), взгляните на findAndModify и на номер $inc operator of update.

+0

Спасибо за подтверждение. Я буду избегать маршрута javascript, как вы предлагаете. Я определенно не хочу отказываться от проблемы с записью. Сначала мне было интересно, можно ли использовать javascript только для вычисления подсчета (например, как-то передать выражение eval в качестве значения поля) и вставить как в исходный код, но, увы, этот вид, вероятно, не поддерживается и не мудр. –

0

Если у вас есть большая коллекция, и вы хотите сохранить CPU, рекомендуется создать другую коллекцию под названием counters, которая имеет только один документ на коллекцию, который вы хотите подсчитать и увеличить размер документа, re каждый раз, когда вы вставляете документ.

See the guidance here.

Похоже, что вы можете поместить функцию JavaScript в вашем запросе, так что, возможно, это может быть сделано в одной поездке, но я не реализовали это в моем приложении, поэтому я не могу подтвердить что.