需求:
查询一张表,根据某字段去重后返回指定信息,支持分页,排序。
逻辑:
1,match查询符合条件的数据
2,利用分组进行去重
3,返回全部字段信息
4,排序
5,分页
mongodb原生语句实现
方法1 返回指定字段
db.getCollection('表名').aggregate([
{
"$match" : {"failure":{$in:["具体失效文件"]}} //查询数组类型字段,根据需求可更改
},
{
"$group" : {
"_id": { "lawId": "$lawId" }, //需要去重的字段
"id":{"$first" :"$_id"},
"lawId": {"$first" :"$lawId"},
"date":{"$first" :"$date"}
}
},
{
"$project": { //设置返回字段,建立在group基础上
"_id": 1,
"id":1,
"lawId": 1,
"date":1
}
},
{"$sort": {"date":-1}}, //排序
{ "$skip":0 }, { "$limit":10 } //分页
])
方法2 返回全部字段
db.getCollection('表名').aggregate([
{
"$match" : {"failure":{$in:["具体失效文件"]}} //查询数组类型字段,根据需求可更改
},
{
"$group" : {
"_id": { "lawId": "$lawId" }, //需要去重的字段
"data":{"$first" :"$$ROOT"} //返回全部字段
}
},
{
"$project": {
"data":1, //返回全部字段
}
},
{"$sort": {"data.dae":-1}}, //根据date.dae字段排序
{ "$skip":0 }, { "$limit":10 } //分页
])
java代码MongoTemplate实现方法2
/**
* 处理group时使用流式操作,务必注意顺序
* params 查询条件
* page 分页信息
* sortKey 排序值
* direction 升序还是降序
* filedsNameList 自定义返回的字段
* groupKey 需要去重的字段
*/
protected Aggregation getGeneralAggregation(Map<String, Object> params,
Page<T> page,
String sortKey,
Direction direction,
List<String> filedsNameList,
String groupKey) {
List<AggregationOperation> aggOptions = new ArrayList<>();
{ // 添加查询条件
List<Criteria> criteriaList = new ArrayList<>();
if (params != null) {
logger.debug("查询参数:" + params);
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (entry.getKey() != null && entry.getValue() != null) {
switch (entry.getValue().getClass().getName()) {
case "java.util.ArrayList":
case "java.util.LinkedList":
criteriaList.add(Criteria.where(entry.getKey()).in(entry.getValue()));
break;
default:
criteriaList.add(Criteria.where(entry.getKey()).is(entry.getValue()));
break;
}
}
}
}
aggOptions.add(Aggregation.match(new Criteria().andOperator(criteriaList.toArray(new Criteria[criteriaList.size()]))));
}
{ // 分组
if (StringUtils.isNotEmpty(groupKey)) {
aggOptions.add(new GroupOperation(Aggregation.fields(groupKey)).first("$$ROOT")
.as("data"));
}
}
{ // 排序
sortKey = "data." + (sortKey == null ? "id" : sortKey);
List<Order> orders = new ArrayList<Order>();
orders.add(new Order(direction, sortKey));
Sort sort = Sort.by(orders);
aggOptions.add(Aggregation.sort(sort));
}
{ // 分页
if (page != null) {
aggOptions.add(Aggregation.skip((long) (page.getPageNumber() > 0
? (page.getPageNumber() - 1) * page.getPageSize()
: 0)));
aggOptions.add(Aggregation.limit(page.getPageSize()));
}
}
{ // 添加返回field
if (CollectionUtils.isNotEmpty(filedsNameList)) {
filedsNameList = filedsNameList.stream()
.map(str -> "data." + str)
.collect(Collectors.toList());
aggOptions.add(Aggregation.project(filedsNameList.toArray(new String[filedsNameList.size()])));
}
}
Aggregation aggregation = Aggregation.newAggregation(aggOptions);
return aggregation;
}
然后调用
agg是上面代码返回的Aggregation
AggregationResults list getMongoTemplate().aggregate(agg, getClassT(),getClassT());
list.getMappedResults(); //获取结果
//agg是上面代码返回的Aggregation
AggregationResults<T> list getMongoTemplate().aggregate(agg, getClassT(),getClassT());
list.getMappedResults(); //获取结果