2011-01-21 104 views
28

我一直在獲取mongo文檔的列的最高值方面有所幫助。我可以對它進行排序並獲得最高/最低限度,但我確信有更好的方法可以做到這一點。在MongoDB中獲取列的最高值

我嘗試了以下(和不同的組合):

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

但它不斷拋出的錯誤。除了排序和獲取頂部/底部,還有什麼好辦法呢?

謝謝!

+0

你應該包括它拋出的錯誤。 – 2011-01-21 19:41:52

回答

48

max()在您對Mongo的SQL中無法達到預期的效果。這可能會在未來的版本中改變,但截至目前,最大值,最小值將與主要用於分片的索引鍵一起使用。

看到http://www.mongodb.org/display/DOCS/min+and+max+Query+Specifiers

不幸的是,現在得到最大價值的唯一辦法是進行排序對收藏價值遞減,並採取第一。

transactions.find("id" => x).sort({"sellprice" => -1}).limit(1).first() 
+3

你也應該做.first,否則你只是得到一個遊標。 – 2011-10-03 22:17:54

0

如果列的索引,那麼排序應該是好的,假設Mongo只是使用索引來獲得一個有序的集合。否則,對集合進行迭代效率更高,同時記下所看到的最大值。例如

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

(道歉,如果我的紅寶石有點舉步維艱,我沒有用很長一段時間 - 但一般的做法應該是從代碼清晰。)

+1

考慮迭代MapReduce !!!這就是爲什麼MongoDB很酷,否則使用平面文件;-) – 2012-06-25 18:18:22

0

假設我用的是Ruby驅動程序(我在底部看到了一個mongodb-ruby標籤),如果我想獲得最大_id(假設我的_id是可排序的),我會執行類似以下的操作。在我的實現中,我的_id是一個整數。

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

獲取集合中最小_id,只是改變:desc:asc

+0

不會find_one()比使用limit()更好嗎? `result = my_collection.find_one({},:sort => ['_id',:desc])` – Anurag 2012-10-11 21:20:28

19

排序可能是矯枉過正。你可以做一組由

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** } 
      }); 
+3

這正是用MongoDB來做到這一點的正確方法! – 2012-06-25 18:24:38

+4

我不會說這是一個矯枉過正的考慮[手冊中的這句話](http://docs.mongodb.org/manual/reference/operator/aggregation/limit/)*「當$ sort立即在$ limit之前在流水線中,$ sort操作只保留前n個結果,其中n是指定的限制「* – aioobe 2014-05-11 18:34:37

3

使用聚合():

db.transactions.aggregate([ 
    {$match: {id: x}}, 
    {$sort: {sellprice:-1}}, 
    {$limit: 1}, 
    {$project: {sellprice: 1}} 
]); 
8
db.collectionName.aggregate(
    { 
    $group : 
    { 
     _id : "", 
     last : 
     { 
     $max : "$sellprice" 
     } 
    } 
    } 
) 
0

下面的查詢做同樣的事情: db.student.find({}, {'_id':1}).sort({_id:-1}).limit(1)

對於我來說,這產生以下結果: { "_id" : NumberLong(10934) }

4

它將工作按您的要求。

transactions.find("id" => x).sort({"sellprice" => -1}).limit(1).first()