使用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 }
答案 0 :(得分:3)
通常情况下,使用聚合SQL查询完成的事情可以在NoSQL存储中以(至少)三种方式进行处理:
使用Map / Reduce。这实际上是通过所有记录,但更优化(适用于多个线程,并在群集中)。这是MongoDB的map/reduce tutorial。
预先计算每个插入物的最大值,并单独存储。因此,无论何时插入记录,都要将其与之前的最大值进行比较,如果更高,则更新数据库中的最大值。
获取内存中的所有内容并在代码中进行计算。这是最微不足道的解决方案。它可能适用于小型数据集。
选择一个而不是另一个取决于您对此最大值的使用。如果很少执行,例如对于某些角落报告,您可以使用map / reduce。如果经常使用,则存储当前最大值
答案 1 :(得分:2)
您可以在sping-data-mongodb中执行此操作。如果排序字段被索引(或@Id字段),Mongo将优化排序/限制组合。这会产生非常快的O(logN)或更好的结果。否则它仍然是O(N)而不是O(N * logN),因为它将使用top-k算法并避免全局排序(mongodb sort doc)。这来自Mkyong's example但是我做了先排序并将限制设置为一秒。
Query query = new Query();
query.with(new Sort(Sort.Direction.DESC, "idField"));
query.limit(1);
MyObject maxObject = mongoTemplate.findOne(query, MyObject.class);
答案 2 :(得分:1)
据我所知,Mongo完全支持排序然后限制:见http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order
通过获取最大/分钟地图缩减将会非常缓慢,应该不惜一切代价避免。
我对Spring Data一无所知,但我可以推荐Morphia来帮助查询。否则,Java驱动程序的基本方法是:
DBCollection coll = db.getCollection("...");
DBCursor curr = coll.find(new BasicDBObject()).sort(new BasicDBObject("order", -1))
.limit(1);
if (cur.hasNext())
System.out.println(cur.next());
答案 3 :(得分:0)
使用聚合$ max。 由于$ max是仅在$ group阶段可用的累加器运算符,因此您需要做一个技巧。 在组运算符中使用任何常量作为_id 让我们以Mongodb site中给出的例子 -
为例使用以下文档考虑销售集合:
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
如果您想了解所有商品的最高价格。
db.sales.aggregate(
[
{
$group:
{
_id: "1", //** This is the trick
maxPrice: { $max: "$price" }
}
}
]
)
请注意" _id"的值 - 它是" 1"。你可以把任何常数......