简体   繁体   English

Mongo 没有 max() function,我该如何解决这个问题?

[英]Mongo does not have a max() function, how do I work around this?

I have a MongoDB collection and need to find the max() value of a certain field across all docs.我有一个 MongoDB 集合,需要在所有文档中找到某个字段的 max() 值。 This value is the timestamp and I need to find the latest doc by finding the largest timestamp.这个值是时间戳,我需要通过找到最大的时间戳来找到最新的文档。 Sorting it and getting the first one gets inefficient really fast.对其进行排序并获得第一个效率非常低。 Shall I just maintain a 'maxval' separately and update it whenever a doc arrives with a larger value for that field?我是否应该单独维护一个“maxval”并在文档到达时对该字段具有更大的值进行更新? Any better suggestions?有更好的建议吗? Thanks much.非常感谢。

if you have an index on the timestsamp field, finding the highest value is efficientl something like如果您在 timestsamp 字段上有一个索引,则找到最高值是有效的,例如

db.things.find().sort({ts:-1}).limit(1)

but if having an index is too much overhead storing the max in a separate collection might be good.但是如果有一个索引的开销太大,将最大值存储在一个单独的集合中可能会很好。

For sure if it will be big collection and if you need always display max timestamp you may need create separate collection and store statistic data there instead of order big collection each time.确定它是否会是大集合,并且如果您需要始终显示最大时间戳,您可能需要创建单独的集合并在那里存储统计数据,而不是每次都订购大集合。

statistic
{
  _id = 1, 
  id_from_time_stamp_collection = 'xxx',
  max_timestamp: value
}

And whenever new doc come just update statistic collection with id = 1(with $gt condition in query, so if new timestamp will be greater than max_timestamp then max_timestamp will be updated, otherwise - no).并且每当新文档出现时,只需更新 id = 1 的统计集合(在查询中使用 $gt 条件,因此如果新时间戳将大于 max_timestamp 则 max_timestamp 将被更新,否则 - 否)。

Also probably you can store and update other statistic data within statistic collection.也可能您可以在统计集合中存储和更新其他统计数据。

Try with db.collection.group尝试使用 db.collection.group

For example, with this collection:例如,对于这个集合:

> db.foo.find()
{ "_id" : ObjectId("..."), "a" : 1 }
{ "_id" : ObjectId("..."), "a" : 200 }
{ "_id" : ObjectId("..."), "a" : 230 }
{ "_id" : ObjectId("..."), "a" : -2230 }
{ "_id" : ObjectId("..."), "a" : 5230 }
{ "_id" : ObjectId("..."), "a" : 530 }
{ "_id" : ObjectId("..."), "a" : 1530 }

You can use group using您可以使用group使用

> db.foo.group({
    initial: { },
    reduce: function(doc, acc) {
        if(acc.hasOwnProperty('max')) {
            if(acc.max < doc.a)
                acc.max = doc.a;
        } else {
            acc.max = doc.a
        }
      }
    })
[ { "max" : 5230 } ]

Since there is no key value in group all the objects are grouped in a single result由于group中没有key ,所有对象都分组在一个结果中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM