Spring Data MongoDB 利用Java Aggregation 聚合分页按条件查询

第一次写这玩意,以前写完就完事了,其实回头想想丢失了好多东西,今天就和大家分享一下,希望对大家有所帮助

我的需求:分页查询数据,将数据根据不同的thingId进行聚合,统计type字段不同类型的个数进行聚合统计后展示,表结构中会有N个不同的thingId,type字段会有1,2,3,4,5,6,7,8这些种类型

数据库字段如下:

"_id" : ObjectId("5a4c797a9f904950b1d5b392"),
    "id" : "1",
    "thingId" : "123456444",
    "deviceId" : "1234566",
    "timestamp" : NumberLong(1514961016000),
    "shoppingMallId" : "123456",
    "orgId" : "123456",
    "orgName" : "洛阳运输公司",
    "plateCode" : "豫CN444",
    "businessType" : "1",
    "type" : "1",
    "startLon" : 123.456,
    "startLat" : 43.256,
    "endLon" : 123.456,
    "endLat" : 43.256,
    "startTime" : NumberLong(1514961016000),
    "endTime" : NumberLong(1514961016000),
    "describe" : "",
    "jsonParam" : ""

引包如下(为了省事直接复制的,自己根据需要删改即可):

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBObject;
import com.vfy.cws.offline.statistics.data.mongo.page.BaseMongoPageable;
import com.vfy.cws.offline.statistics.data.statistics.mapper.VehicleEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

聚合代码如下:

其中分页这个操作有点多余,分页对象存储了页数和每页条数,也可以直接将这两个字段值传递给聚合函数中的分页处理

if (json.getInteger("pageNumber") != null){
        pageable = BaseMongoPageable.setVehicleEventAggregationPageableParams(json);
    }


public JSONObject queryAggregationDBData(JSONObject json){
    Pageable pageable = null;
    //分页
    if (json.getInteger("pageNumber") != null){
        pageable = BaseMongoPageable.setVehicleEventAggregationPageableParams(json);
    }
    List<VehicleEvent> pageContentslist = null;
    String plateCode = json.getString("keyWord");
    String orgId = json.getString("orgId");
    JSONObject jsonObject = null;
    JSONArray array = getAggregation(orgId,plateCode,pageable);
    long count = getAggregationCount(orgId,plateCode,pageable);
           jsonObject=setQueryAggregationResultList(array,count,pageable.getPageNumber(),pageable.getPageSize());
    return jsonObject;
}

public JSONArray getAggregation(String orgId,String plateCode,Pageable pageable) {
    Criteria criteria = new Criteria();
    if(plateCode.equals("all")){
        criteria = Criteria.where("orgId").is(orgId);
    }else{
        criteria = Criteria.where("orgId").is(orgId).andOperator(Criteria.where("plateCode").regex(plateCode));
    }
    Aggregation agg = Aggregation.newAggregation(
            Aggregation.match(criteria),//查询条件
            //聚合统计,按照thingId,type2个字段聚合,count计数按最后一个字段计数
            Aggregation.group("thingId","type").count().as("count")
                    .first("thingId").as("thingId").first("plateCode").as("plateCode")
                    .first("orgId").as("orgId").first("orgName").as("orgName")
                    .first("shoppingMallId").as("shoppingMallId"),
            //再次聚合,按照thingId再次聚合
            Aggregation.group("thingId").push(new BasicDBObject("type", "$_id.type").append("count", "$count")).as("item")
                    .first("thingId").as("thingId").first("plateCode").as("plateCode")
                    .first("orgId").as("orgId").first("orgName").as("orgName")
                    .first("shoppingMallId").as("shoppingMallId"),
            Aggregation.sort(pageable.getSort()),//排序字段
            //分页操作,pageNumber为当前页数,pageSize为每页显示条数
            Aggregation.skip(pageable.getPageNumber()>1?(pageable.getPageNumber()-1)*pageable.getPageSize():0),
            Aggregation.limit(pageable.getPageSize())
    );
    AggregationResults<Map> results = mongoTemplate.aggregate(agg,VehicleEvent.class,Map.class);
    List<Map> listVehicleSensors =  results.getMappedResults();
    JSONArray json = transportMap(listVehicleSensors);
    return json;
}
public long getAggregationCount(String orgId,String plateCode,Pageable pageable) {
    Criteria criteria = new Criteria();
    if(plateCode.equals("all")){
        criteria = Criteria.where("orgId").is(orgId);
    }else{
        criteria = Criteria.where("orgId").is(orgId).andOperator(Criteria.where("plateCode").regex(plateCode));
    }
    Aggregation agg = Aggregation.newAggregation(
            Aggregation.match(criteria),//条件
            Aggregation.group("thingId","type").count().as("count")
                    .first("thingId").as("thingId").first("plateCode").as("plateCode")
                    .first("orgId").as("orgId").first("orgName").as("orgName")
                    .first("shoppingMallId").as("shoppingMallId"),
            Aggregation.group("thingId").push(new BasicDBObject("type", "$_id.type").append("count", "$count")).as("item")
                    .first("thingId").as("thingId").first("plateCode").as("plateCode")
                    .first("orgId").as("orgId").first("orgName").as("orgName")
                    .first("shoppingMallId").as("shoppingMallId")
    );
    AggregationResults<Map> results = mongoTemplate.aggregate(agg,VehicleEvent.class,Map.class);
    int count = results.getMappedResults().size();
    return count;
}

处理得到查询结果的的代码如下:

public JSONArray transportMap(List<Map> listVehicleSensors){
    JSONArray arrayList = new JSONArray();
    if(listVehicleSensors != null && listVehicleSensors.size() > 0){
        for (Map list :listVehicleSensors){
            JSONObject json = new JSONObject();
            String strMap = JSON.toJSONString(list);
            JSONObject js = JSON.parseObject(strMap);
            json.put("thingId",js.getString("thingId"));
            json.put("plateCode",js.getString("plateCode"));
            json.put("orgId",js.getString("orgId"));
            json.put("orgName",js.getString("orgName"));
            json.put("shoppingMallId",js.getString("shoppingMallId"));
            json.put("timesNum",0);
            json.put("parkingLotNum",0);
            json.put("disposalSiteNum",0);
            json.put("projectNum",0);
            json.put("heavyLoadNum",0);
            json.put("topCoverCloseNum",0);
            json.put("topCoverOpenNum",0);
            json.put("liftNum",0);
            JSONArray array = js.getJSONArray("item");
            if(array != null && array.size() > 0){
                for (int i=0;i<array.size();i++){
                    JSONObject jo = array.getJSONObject(i);
                    String type = jo.getString("type");
                    switch (type){
                        case "8":
                            json.put("timesNum",jo.getInteger("count"));
                            break;
                        case "7":
                            json.put("parkingLotNum",jo.getInteger("count"));
                            break;
                        case "6":
                            json.put("disposalSiteNum",jo.getInteger("count"));
                            break;
                        case "5":
                            json.put("projectNum",jo.getInteger("count"));
                            break;
                        case "4":
                            json.put("heavyLoadNum",jo.getInteger("count"));
                            break;
                        case "3":
                            json.put("topCoverCloseNum",jo.getInteger("count"));
                            break;
                        case "2":
                            json.put("topCoverOpenNum",jo.getInteger("count"));
                            break;
                        case "1":
                            json.put("liftNum",jo.getInteger("count"));
                            break;
                    }
                }
            }
            arrayList.add(json);
        }
    }
    return arrayList;
}
public JSONObject setQueryAggregationResultList(JSONArray json, long count, int pageNumber, int pageSize) {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("pageNumber", pageNumber);
    jsonObject.put("pageSize", pageSize);
    jsonObject.put("totalNumber", (int) count);
    JSONArray arr = new JSONArray();
    if (json != null && json.size() > 0) {
        for (int i = 0; i < json.size(); i++) {
            JSONObject o = json.getJSONObject(i);
            arr.add(o);
        }
    }
    jsonObject.put("content", arr);
    return jsonObject;
}

得到结果如下:

"data": {
        "totalNumber": 6,
        "pageNumber": 2,
        "pageSize": 5,
        "content": [
            {
                "topCoverCloseNum": 2,
                "shoppingMallId": "123456",
                "orgName": "洛阳运输公司",
                "topCoverOpenNum": 1,
                "heavyLoadNum": 2,
                "plateCode": "豫CN520",
                "orgId": "123456",
                "parkingLotNum": 0,
                "thingId": "123456",
                "disposalSiteNum": 2,
                "projectNum": 2,
                "liftNum": 1,
                "timesNum": 1
            }
        ]
    }


你可能感兴趣的:(Spring,Data,MongoDB,Spring,Data,MongoDB,Aggregation,聚合分页,按条件查询)