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 ; }}");

   

    GroupByResults<DeviceGroupByResult> results =

          

        //criteria: 篩選條件 , CTL_HEART_BEAT:集合名稱/表名 ,DeviceGroupByResult.class:接收數據對象

        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++;

                }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM