我使用聚合来从mongodb获取记录.
$result = $collection->aggregate(array(
array('$match' => $document),
array('$group' => array('_id' => '$book_id', 'date' => array('$max' => '$book_viewed'), 'views' => array('$sum' => 1))),
array('$sort' => $sort),
array('$skip' => $skip),
array('$limit' => $limit),
));
Run Code Online (Sandbox Code Playgroud)
如果我无限制地执行此查询,则将获取10条记录.但我想保持限制为2.所以我想得到总记录数.如何进行聚合?请指教.谢谢
我想执行一个执行基本分页的聚合查询:
company_idorder_number100并传递其余部分2并传递它们以下是查询的细分:
db.Order.collection.aggregate([
Run Code Online (Sandbox Code Playgroud)
这会找到所有匹配的文档:
{ '$match' : { "company_id" : ObjectId("54c0...") } },
Run Code Online (Sandbox Code Playgroud)
这会对文件进行排序:
{ '$sort' : { 'order_number' : -1 } },
Run Code Online (Sandbox Code Playgroud)
这会对文档进行计数并传递未经修改的文档,但我确信这样做是错误的,因为事情变得怪异了:
{
'$group' : {
'_id' : null,
'count' : { '$sum' : 1 },
'entries' : { '$push' : "$$ROOT" }
}
},
Run Code Online (Sandbox Code Playgroud)
这似乎跳过一些文件:
{ "$skip" : 100 },
Run Code Online (Sandbox Code Playgroud)
这应该限制文档,但它不会:
{ "$limit" : 2 },
Run Code Online (Sandbox Code Playgroud)
这会返回计数,但它不会返回数组中的文档,而是返回包含每个字段的数组:
{ '$project' : {
'count' : 1,
'entries' …Run Code Online (Sandbox Code Playgroud) 为了提高效率,Mongo文档建议限制语句紧跟在排序语句之后,最终会有点荒谬:
collection.find(f).sort(s).limit(l).skip(p)
Run Code Online (Sandbox Code Playgroud)
我说这有点荒谬,因为它似乎说先拿l项,然后放下那些l的第一个p.由于p通常大于l,你认为你最终没有结果,但实际上你最终会得到l结果.
聚合效果更符合您的预期:
collection.aggregate({$unwind: u}, {$group: g},{$match: f}, {$sort: s}, {$limit: l}, {$skip: p})
Run Code Online (Sandbox Code Playgroud)
如果p> = l,则返回0结果.
collection.aggregate({$unwind: u}, {$group: g}, {$match: f}, {$sort: s}, {$skip: p}, {$limit: l})
Run Code Online (Sandbox Code Playgroud)
但是文档似乎暗示如果匹配返回的结果集大于工作内存,则会失败.这是真的?如果是这样,是否有更好的方法对通过聚合返回的结果集执行分页?
资料来源:本页末尾的"版本2.4更改"评论:http: //docs.mongodb.org/manual/reference/operator/aggregation/sort/
我在对聚合管道的结果进行分页时遇到了一些麻烦。在查看了In spring data mongodb 如何实现分页进行聚合后,我想出了一个感觉像 hacky 的解决方案。我首先执行匹配查询,然后按我搜索的字段分组,并对结果进行计数,将值映射到一个私有类:
private long getCount(String propertyName, String propertyValue) {
MatchOperation matchOperation = match(
Criteria.where(propertyName).is(propertyValue)
);
GroupOperation groupOperation = group(propertyName).count().as("count");
Aggregation aggregation = newAggregation(matchOperation, groupOperation);
return mongoTemplate.aggregate(aggregation, Athlete.class, NumberOfResults.class)
.getMappedResults().get(0).getCount();
}
private class NumberOfResults {
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,我就能够为我返回的页面对象提供一个“总”值:
public Page<Athlete> findAllByName(String name, Pageable pageable) {
long total = getCount("team.name", name);
Aggregation aggregation = getAggregation("team.name", name, pageable); …Run Code Online (Sandbox Code Playgroud) spring-data-mongodb spring-boot spring-restcontroller spring-rest