2011-01-21 99 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()