mongoTemplate工作中常用方式

MongoTemplate官方文檔:

https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.aggregation.supported-aggregation-operations

一、增刪改查

原生mongo:

Query對象

1、 創建一個query對象(用來封裝所有條件對象),再創建一個criteria對象(用來構建條件)

2 、精準條件:criteria.and("key").is("條件") 模糊條件:criteria.and("key").regex("條件")

3、封裝條件:query.addCriteria(criteria)

4、大於(創建新的criteria):Criteria gt = Criteria.where("key").gt("條件") 小於(創建新的criteria):Criteria lt = Criteria.where("key").lt("條件") 5、Query.addCriteria(new Criteria().andOperator(gt,lt));

6、一個query中只能有一個andOperator()。其參數也可以是Criteria數組。

7、排序 :query.with(new Sort(Sort.Direction.ASC, "age"). and(new Sort(Sort.Direction.DESC, "date")))

二、mongoTemplate分組排序、複雜操作

   

分組方法

理解難度

性能對比

是否提倡

mongoTemplate.group();

對比來將這個簡單點

70w數據需要2分30秒

在springBoot新的集成環境下,mongoDB已經淘汰該方法了

mongoTemplate.aggregation();

理解之後特別好用

同環境下只需10秒不到

使用中

   1、mongoTemplate.group(); 分組但並不能使用排序,已經廢棄

        //封裝具體的篩選條件
        Criteria criteria = new Criteria();
        criteria.andOperator(
                // 篩選大於 getMsgTime > startTime 和 getMsgTime < endTime 的數據 (getMsgTime)
                Criteria.where("getMsgTime").gte(startTime),
                Criteria.where("getMsgTime").lte(endTime));
        //mongoDB按"deviceCode"分組 ,這裏會默認保留分組字段
        GroupBy groupBy = GroupBy.key("deviceCode")
                //新增保留字段 並初始化
                .initialDocument("{ count: 0 , onlineCount: 0 , lastTime: 0}")
                //對分組後的數據進行運算 doc代表當前文檔,prev代表結果文檔 func裏面可以使用js語法
                .reduceFunction("function(doc, prev) { prev.count++ ; if(doc.ctlStatus == 1){prev.onlineCount += 1 ;prev.lastTime = doc.getMsgTime ; }}");
        //criteria: 篩選條件 , CTL_HEART_BEAT:集合名稱/表名 ,DeviceGroupByResult.class:接收數據對象
        GroupByResults<DeviceGroupByResult> results = mongoTemplate.group(criteria, "CTL_HEART_BEAT", groupBy, DeviceGroupByResult.class);

        /**這裏的接收數據 對象 指的是 將 保留字段 封裝成一個對象,並添加get/set方法
         * 這裏 DeviceGroupByResult.class 類中就包含 deviceCode、count、onlineCount、lastTime 這些屬性。
         */
        //對結果集進行處理 這裏只能拿到iterator對象,在我看來itertator並沒有List集合 香
        Iterator<DeviceGroupByResult> iterator = results.iterator();
        while (iterator.hasNext()) {
            //看了下源碼這個地方 result.iterator 返回的就是就是結果集 但是隻能用迭代器讀取
            DeviceGroupByResult deviceGroupByResult = iterator.next();
        }

2、mongoTemplate.aggregation(); 分組並排序,推薦使用這種方式

        //封裝具體的篩選條件
        Criteria criteria = new Criteria();
        criteria.andOperator(
                // 篩選大於 getMsgTime > startTime 和 getMsgTime < endTime 的數據 (getMsgTime)
                Criteria.where("getMsgTime").gte(startTime),
                Criteria.where("getMsgTime").lte(endTime));
        //mogoDB按device_code分組查詢
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),//添加篩選方法
                Aggregation.group("deviceCode").first("deviceCode").as("deviceCode") //利用deviceCode分組並保留該字段
                        .last("getMsgTime").as("lastTime")//取最後時間作爲保留
                        .count().as("count")//統計分個數
                        //這裏的ctlStatus在mongoDB裏面是以字符串存儲,而我想統計它們之和,但是字符串不能直接相加sum(),所以只能先存到List中
                        .push("ctlStatus").as("currentCtlStatusList")
                        .push("getMsgTime").as("cuurentCtlGetTimeList")//這裏之所以把時間也push上去,是因爲我要取ctlstatus=1時候的時間
                //這裏排序放在分組後面,所以指定的字段只能是lastTime,而放在分組前面就需要指定getMsgTime數據庫字段
                //而且使用sort要注意,sort我發現在70w數據面前 就歇菜了 ,而且回報錯
                Aggregation.sort(Sort.by(Sort.Order.asc("lastTime")))
        );

        //aggegation:所有條件的封裝 , CTL_HEART_BEAT:集合/表 ,DeviceGroupByResult.class:接收數據對象
        AggregationResults<DeviceGroupByResult> deviceGroupByResults = mongoTemplate.aggregate(aggregation, "CTL_HEART_BEAT", DeviceGroupByResult.class);
        //這裏就很友好了
        List<DeviceGroupByResult> list = deviceGroupByResults.getMappedResults();

3、循環查詢(可能你會遇見需要你循環幾次的操作)

        Criteria criteria = new Criteria();
        //timeFrames  時間集合
        for (String time : timeFrames) {
            //將篩選條件封裝到agregaton
            Aggregation aggregation = Aggregation.newAggregation(
                    //注意這裏使用的是 new criteria.adddOperator(criteria) 每次循環都帶一個全新的Criteria條件
                    //按照正常邏輯 是不需要在外面 包一層,但是如你這樣做了
                    //循環第一遍沒問題,第二遍嘿嘿  會提示  對一個參數做了多次篩選,所以這裏做了一個隱式傳參
                    Aggregation.match(new Criteria().andOperator(criteria.where("STATISTICS_YEAR").is(time), criteria)),
                    Aggregation.group("STATISTICS_TIME").first("STATISTICS_TIME").as("time").sum("CAR_FLOW").as("count"),
                    Aggregation.sort(Sort.by(Sort.Order.asc("time")))
            );
            AggregationResults<CarFlowResultVO> carFlowResultVOs = mongoTemplate.aggregate(aggregation, tableName, CarFlowResultVO.class);
            carFlowResultVOList = carFlowResultVOs.getMappedResults();
            carFlowResultVOMap.put(String.valueOf(count), carFlowResultVOList);
            carFlowResultVOList = new ArrayList<>();
            count++;
        }

 轉載:https://www.cnblogs.com/tiankx/p/13957842.html

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