Получение максимального значения столбца в MongoDB

Мне нужна помощь в получении максимального значения столбца для документа монго. Я могу отсортировать его и получить верх/низ, но я уверен, что есть лучший способ сделать это.

Я пробовал следующее (и разные комбинации):

transactions.find("id" => x).max({"sellprice" => 0})

Но постоянно выдает ошибки. Какой хороший способ сделать это, кроме сортировки и получения верхней/нижней части?

Благодарю вас!


person roloenusa    schedule 21.01.2011    source источник
comment
Вы должны включить ошибки, которые он выдает.   -  person Andy Lindeman    schedule 21.01.2011


Ответы (8)


max() работает не так, как вы ожидаете в SQL для Mongo. Возможно, это изменится в будущих версиях, но на данный момент max,min должны использоваться с индексированными ключами в первую очередь внутри для сегментирования.

см. http://www.mongodb.org/display/DOCS/min+and+max+Query+Specifiers

К сожалению, на данный момент единственный способ получить максимальное значение — отсортировать описание коллекции по этому значению и взять первое.

transactions.find("id" => x).sort({"sellprice" => -1}).limit(1).first()
person Michael Papile    schedule 21.01.2011

Сортировка может быть излишней. Вы можете просто создать группу

db.messages.group(
           {key: { created_at:true },
            cond: { active:1 },
            reduce: function(obj,prev) { if(prev.cmax<obj.created_at) prev.cmax = obj.created_at; },
            initial: { cmax: **any one value** }
            });
person Mayur Rustagi    schedule 25.11.2011
comment
Я бы не сказал, что это излишество, учитывая эту цитату из руководства Когда $sort непосредственно предшествует $limit в конвейере, операция $sort поддерживает только первые n результатов по мере своего продвижения, где n – указанный лимит - person aioobe; 11.05.2014

Пример кода оболочки mongodb для вычисления агрегатов.

см. ручную запись mongodb для группы (многие приложения) :: http://docs.mongodb.org/manual/reference/aggregation/group/#stage._S_group

В приведенном ниже примере замените $vars ключом вашей коллекции и целевой переменной.

db.activity.aggregate( 
  { $group : {
      _id:"$your_collection_key", 
      min: {$min : "$your_target_variable"}, 
      max: {$max : "$your_target_variable"}
    }
  } 
)
person jatal    schedule 05.06.2013

Используйте агрегат():

db.transactions.aggregate([
  {$match: {id: x}},
  {$sort: {sellprice:-1}},
  {$limit: 1},
  {$project: {sellprice: 1}}
]);
person Vincent    schedule 23.05.2013

Он будет работать в соответствии с вашим требованием.

transactions.find("id" => x).sort({"sellprice" => -1}).limit(1).first()
person Shariq Ansari    schedule 30.03.2015
comment
В чем смысл этого ответа? Повторить принятый ответ? - person Dan Dascalescu; 07.10.2018

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

max = nil
coll.find("id" => x).each do |doc| 
    if max == nil or doc['sellprice'] > max then
        max = doc['sellprice'] 
    end
end

(Извините, если мой Ruby немного неуклюж, я давно им не пользовался, но общий подход должен быть понятен из кода.)

person Simon Whitaker    schedule 21.01.2011
comment
Подумайте о повторении с MapReduce !!! Вот почему MongoDB — это круто, иначе используйте плоские файлы ;-) - person Thomas Decaux; 25.06.2012

Предполагая, что я использую драйвер Ruby (я видел тег mongodb-ruby внизу), я бы сделал что-то вроде следующего, если бы хотел получить максимальное _id (при условии, что мой _id сортируется). В моей реализации мой _id был целым числом.

result = my_collection.find({}, :sort => ['_id', :desc]).limit(1)

Чтобы получить минимум _id в коллекции, просто измените :desc на :asc

person briangonzalez    schedule 20.09.2011
comment
Разве find_one() не лучше, чем использование limit()? result = my_collection.find_one({}, :sort => ['_id', :desc]) - person Anurag; 12.10.2012

Следующий запрос делает то же самое: db.student.find({}, {'_id':1}).sort({_id:-1}).limit(1)

Для меня это дало следующий результат: { "_id" : NumberLong(10934) }

person Manish    schedule 03.11.2014