【发布时间】:2020-03-05 08:06:55
【问题描述】:
我有一个搜索条件,我必须提供搜索结果的分页以及集合中的记录总数。假设在 10 条记录的集合中,我只想获取 5 条记录以及总记录数。结果数据,我想将它们推送到具有 count 和 searchResult 属性的单独对象中。记录总数必须映射到计数,并将分页记录映射到 searchResult。我已经应用了聚合,它运行良好,除了包含 CountOperation 和 ProjectOperation。当我在聚合中添加 countOperation 和 ProjectOperation 时,它给出了无效的引用“_id!”例外。 预期的查询将是这样的。
db.customer.aggregate([
{
$facet:{
searchResult:[{$match:{"name" : { "$regex" : "xyz", "$options" : "i" }}}],
count: [{ $count: 'count' }]
}
}
])
输出会是这样的。
[
{
"searchResult":[{...},{...},{...}, ...],
"count":[{"count":100}]
}
]
搜索逻辑:
public List<SampleSearchResult> findListByRequest(ListRequest queryParams, Class<T> clazz) {
String collectionName = mongoTemplate.getCollectionName(clazz);
MatchOperation matchOperation = getMatchOperation(queryParams);
SortOperation sortOperation = getSortOperation(queryParams);
SkipOperation skipOperation = Aggregation.skip((long) queryParams.getPageNumber() * queryParams.getSize());
LimitOperation limitOperation = Aggregation.limit(queryParams.getSize());
CountOperation countOperation = Aggregation.count().as("count");
ProjectionOperation projectionOperation = getProjectionOperation();
AggregationResults<SampleSearchResult> results = mongoTemplate
.aggregate(Aggregation.newAggregation(matchOperation, sortOperation, skipOperation, limitOperation, countOperation, projectionOperation ), collectionName, SampleSearchResult.class);
return (List<SampleSearchResult>) results.getMappedResults();
}
投影操作逻辑
private ProjectionOperation getProjectionOperation() {
return Aggregation.project("count").and("_id").previousOperation();
}
排序操作逻辑:
private SortOperation getSortOperation(ListRequest listRequest) {
// setting defaults
if (StringUtils.isEmpty(listRequest.getSortBy())) {
listRequest.setSortBy("_id");
listRequest.setAsc(false);
}
Sort sort = listRequest.isAsc() ? new Sort(Direction.ASC, listRequest.getSortBy())
: new Sort(Direction.DESC, listRequest.getSortBy());
return Aggregation.sort(sort);
}
比赛操作逻辑:
private MatchOperation getMatchOperation(ListRequest listRequest) {
Criteria criteria = new Criteria();
// build match operation logic with listRequest parameters
return Aggregation.match(criteria);
}
将保存聚合结果的结果对象
public class SampleSearchResult {
private List<Object> searchResult;
private int count;
public List<Object> getSearchResult() {
return searchResult;
}
public void setSearchResult(List<Object> searchResult) {
this.searchResult = searchResult;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
我需要正确编写 CountOperation 和 ProjectionOperation 以将数据映射到 SampleSearchResult 但我不是那么高效,因为我是 MongoDB 操作的新手。
【问题讨论】:
-
问题:
_id!的感叹号是什么?这真的会出现在标准错误上吗?另外:您是说.aggregate(Aggregation.newAggregation(matchOperation, sortOperation, skipOperation, limitOperation ), collectionName, SampleSearchResult.class);有效,但添加countOperation, projectionOperation无效? -
是的,在countOperation和projectOperation的时候添加。感叹号出现在 stderr 上。
标签: mongodb spring-boot