使用Spring Data Mongodb,是否可以获得字段的最大值而无需拉动和迭代整个集合?

jer*_*ary 5 mongodb nosql spring-data spring-data-mongodb

使用mongoTemplate.find(),我指定一个可以调用的查询.limit().sort():

.limit()返回一个Query对象
.sort()返回一个Sort对象

鉴于此,我可以说Query().limit(int).sort(),但这不执行所需的操作,它只是对有限的结果集进行排序.

我不能调用Query().sort().limit(int),因为.sort()返回一个Sort()

所以使用Spring Data,如何执行mongoDB shell中显示的以下内容?也许有办法传递一个我还没有找到的原始查询?

如果需要,我可以扩展Paging接口......似乎没有任何帮助.谢谢!

> j = { order: 1 }
{ "order" : 1 }
> k = { order: 2 }
{ "order" : 2 }
> l = { order: 3 }
{ "order" : 3 }
> db.test.save(j)
> db.test.save(k)
> db.test.save(l)
> db.test.find()
{ "_id" : ObjectId("4f74d35b6f54e1f1c5850f19"), "order" : 1 }
{ "_id" : ObjectId("4f74d3606f54e1f1c5850f1a"), "order" : 2 }
{ "_id" : ObjectId("4f74d3666f54e1f1c5850f1b"), "order" : 3 }
> db.test.find().sort({ order : -1 }).limit(1)
{ "_id" : ObjectId("4f74d3666f54e1f1c5850f1b"), "order" : 3 }
Run Code Online (Sandbox Code Playgroud)

Whe*_*zil 5

您可以在 sping-data-mongodb 中执行此操作。如果排序字段被索引(或@Id 字段),Mongo 将优化排序/限制组合。这会产生非常快的 O(logN) 或更好的结果。否则它仍然是 O(N) 而不是 O(N*logN) 因为它将使用 top-k 算法并避免全局排序 ( mongodb sort doc)。这是来自Mkyong 的示例,但我先进行排序并将限制设置为一秒。

Query query = new Query();
query.with(new Sort(Sort.Direction.DESC, "idField"));
query.limit(1);
MyObject maxObject = mongoTemplate.findOne(query, MyObject.class);
Run Code Online (Sandbox Code Playgroud)


Boz*_*zho 3

通常,在 NoSQL 存储中(至少)可以通过三种方式处理使用聚合 SQL 查询完成的事情:

  • 与映射/减少。这有效地遍历了所有记录,但更加优化(适用于多个线程,并且在集群中)。这是MongoDB 的Map/Reduce 教程。

  • 预先计算每个插入的最大值,并单独存储。因此,每当插入一条记录时,都会将其与之前的最大值进行比较,如果更大,则更新数据库中的最大值。

  • 获取内存中的所有内容并在代码中进行计算。这是最简单的解决方案。它可能适用于小数据集。

选择其中之一取决于您对该最大值的使用情况。如果很少执行,例如对于一些角落报告,您可以使用 map/reduce。如果经常使用,则存储当前的最大值。