mongodb按照時間分組統計

使用spring data mongodb v1.8

需求1、

數據結構如下。說明:改集合記錄的是公司各個系統的訪問情況(localPath表示系統,requestTime 表示請求時間,字符串類型,)

image.png

需求:選中某一天,然後按照系統和小時進行分組,統計這一天中每個小時各個系統的訪問情況。

業務代碼:

Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("createTime").lt(DateUtil.addDay(sdf.parse(sdf.format(date)), 1)), Criteria.where("createTime").gte(sdf.parse(sdf.format(date))));
// 匹配查詢
MatchOperation matchOperation = Aggregation.match(criteria);// localPath
// 返回參數
ProjectionOperation return1 = Aggregation.project("localPath").andExpression("substr(requestTime,11,2)").as("dimension");
// 按條件分組
GroupOperation go2 = Aggregation.group("dimension", "localPath").count().as("times");
// 設置排序
SortOperation sortOperation = Aggregation.sort(Sort.Direction.ASC, "localPath", "dimension");
// 構建參數
Aggregation aggregation = Aggregation.newAggregation(matchOperation, return1, go2, sortOperation);
// 分組聚合查詢
AggregationResults<SysCountResultVo> aggregate = mongoTemplate.aggregate(aggregation, getCollectionName(date), SysCountResultVo.class);
// 獲取結果
List<SysCountResultVo> resultVos = aggregate.getMappedResults();

SysCountResultVo類

public class SysCountResultVo {
    /**次數**/
    private int times;
    /**服務**/
    private String localPath;
    /**維度**/
    private String dimension;

    public int getTimes() {
	return times;
    }

    public void setTimes(int times) {
	this.times = times;
    }

    public String getLocalPath() {
	return localPath;
    }

    public void setLocalPath(String localPath) {
	this.localPath = localPath;
    }

    public String getDimension() {
	return dimension;
    }

    public void setDimension(String dimension) {
	this.dimension = dimension;
    }

    @Override
    public String toString() {
	return "SysCountResultVo [times=" + times + ", localPath=" + localPath + ", dimension=" + dimension + "]";
    }

}

需求二、

數據結構如下。說明:該集合存儲的是投遞信息(isView 表示的類型,deliveryTime 表示 投遞時間)

image.png

需求:

選擇一個時間段,要求按天和投遞類型進行分組統計。

難點:

mongodb存儲的時間是utc時間,這個時間比本地時間少8個小時,例如 本地時間爲:2018.7.18 00:00:00日,mongodb中存儲的是 2018.7.17 t16:00:00z之類的東西。

按天統計的時候,如果集合中存了字符處,可以使用需求1中的方法,使用substr函數進行處理。但是如果像需求2中,沒有存儲字符串,怎麼辦?以下是我的思路。

service

Criteria criteria = new Criteria();
	/**此處設置匹配條件**/
	// 匹配查詢
	MatchOperation matchOperation = Aggregation.match(criteria);
	// 返回參數,對日期進行處理
	ProjectionOperation return1 = Aggregation.project("isView").andExpression("year(deliveryTime)").as("year").andExpression("month(deliveryTime)").as("month").andExpression("dayOfMonth(deliveryTime)").as("day").andExpression("hour(deliveryTime)").as("hour");
	// 按條件分組
	GroupOperation go2 = Aggregation.group("isView", "year", "month", "day", "hour").count().as("times");
	// 設置排序
	SortOperation sortOperation = Aggregation.sort(Sort.Direction.ASC, "times");
	// 構建參數
	Aggregation aggregation = Aggregation.newAggregation(matchOperation, return1, go2, sortOperation);
	// 分組聚合查詢
	AggregationResults<SysCountResultVo> aggregate = mongoTemplate.aggregate(aggregation, "resumeDeliveryRecordVo", SysCountResultVo.class);
	// 獲取結果
	List<SysCountResultVo> resultVos = aggregate.getMappedResults();

SysCountResultVo類

public class SysCountResultVo {
    /**次數**/
    private int times;
    /**服務**/
    private String isView;
    /**年**/
    private Integer year;
    /**月**/
    private Integer month;
    /**日**/
    private Integer day;
    /**小時**/
    private Integer hour;
    /**時間**/
    private String time;

    private String isViewStr;

    public int getTimes() {
	return times;
    }

    public void setTimes(int times) {
	this.times = times;
    }

    public String getIsView() {
	return isView;
    }

    public void setIsView(String isView) {
	this.isView = isView;
    }

    public Integer getYear() {
	return year;
    }

    public void setYear(Integer year) {
	this.year = year;
    }

    public Integer getMonth() {
	return month;
    }

    public void setMonth(Integer month) {
	this.month = month;
    }

    public Integer getDay() {
	return day;
    }

    public void setDay(Integer day) {
	this.day = day;
    }
    // 此處爲重點,如果時>=16,則認爲是下一天
    public String getTime() {
	try {
	    if (hour >= 16) {
		return DateUtil.date2DateStr(DateUtil.addDay(DateUtil.dateStr2Date(this.getYear() + "-" + this.getMonth() + "-" + this.getDay(), DateUtil.PATTERN_DTSHORTLINE), 1), DateUtil.PATTERN_DTSHORTLINE);
	    }
	    return this.getYear() + "-" + this.getMonth() + "-" + this.getDay();
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return null;
    }

    public Integer getHour() {
        return hour;
    }

    public void setHour(Integer hour) {
        this.hour = hour;
    }

    public void setTime(String time) {
	this.time = time;
    }

    public String getIsViewStr() {
	return Integer.valueOf(isView) == 1 ? "未查看" : Integer.valueOf(isView) == 2 ? "待溝通" : Integer.valueOf(isView) == 4 ? "已查看" : Integer.valueOf(isView) == 6 ? "不合適" : "其他";
    }

    public void setIsViewStr(String isViewStr) {
	this.isViewStr = isViewStr;
    }

    @Override
    public String toString() {
	return "time:" + getTime() + ";times:" + getTimes() + ";isView:" + getIsView();
    }

}

可能說明的不是很清楚,不過可以作爲一個參考。我的QQ:1208576787,如有什麼問題,可以加QQ討論下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章