使用mongoTemplate實(shí)現(xiàn)多條件加分組查詢方式
先來一個(gè)常見的錯(cuò)誤信息:
Due to limitations of the com.mongodb.BasicDocument, you can't add a second '$and' expression specified as '$and :
錯(cuò)誤原因:
在一個(gè) Criteria 對(duì)象中調(diào)用了多次 andOperator() 方法
mongoTemplate實(shí)現(xiàn)多條件查詢
多個(gè)條件的查詢只需要?jiǎng)?chuàng)建 Query 對(duì)象,然后把需要添加的條件使用 Query 對(duì)象的 addCriteria() 方法
// 場(chǎng)景:查詢指定時(shí)間段內(nèi),狀態(tài)為1的數(shù)據(jù) // 入?yún)l件 :beginTime ,endTime ,statue // mongodb字段:time , state // 存放條件的對(duì)象 Query condition= new Query(); // 判斷時(shí)間是否為空 if(beginTime != null && endTime != null){ // 添加大于開始時(shí)間小于結(jié)束時(shí)間的條件 condition.addCriteria(Criteria.where("time").gte(beginTime).lte(endTime)); }else{ // 其中一個(gè)為空 分別進(jìn)行判斷 if(beginTime != null){ condition.addCriteria(Criteria.where("time").gte(beginTime)); } if(endTime != null){ condition.addCriteria(Criteria.where("time").lte(endTime)); } } // 添加狀態(tài)為1條件 if(statue!=null){ condition.addCriteria(Criteria.where("state").is(statue)); }
條件有了后再調(diào)用 mongoTemplate.find(condition,返回類型.class,collectionName)
但是...想要分組,得調(diào)用 mongoTemplate.group(Criteria criteria , String inputCollectionName , GroupBy groupBy , Class<T> entityClass) 方法 (不是說只能這樣才能分組,而是我通過這種方法實(shí)現(xiàn)了分組查詢)
朋友們,第一個(gè)參數(shù)條件只能入?yún)?nbsp;Criteria 對(duì)象,而不能入?yún)?nbsp;Query 對(duì)象
結(jié)果我發(fā)現(xiàn) Criteria 對(duì)象有 andOperator(Criteria ... criteria) 方法
這個(gè)方法就厲害了,可以入?yún)?shù)組,也就是說
我們可以把查詢條件先存放到一個(gè)集合里面(因?yàn)閿?shù)組需要定義長(zhǎng)度,如果條件個(gè)數(shù)不確定,就不能直接定義數(shù)組),然后把集合放入數(shù)組中,再把數(shù)組入?yún)?nbsp;andOperator(Criteria ... criteria) 方法
// 場(chǎng)景:查詢指定時(shí)間段內(nèi),狀態(tài)為1的數(shù)據(jù) // 入?yún)l件 :beginTime ,endTime ,statue // mongodb字段:time , state // 定義一個(gè)存放條件的集合 List<Criteria> criteriaList = new ArrayList<>(); // 定義一個(gè)存放條件的數(shù)組(暫時(shí)不給長(zhǎng)度) Criteria[] criteriaArray = {}; // 判斷時(shí)間是否為空 if(beginTime != null && endTime != null){ // 添加大于開始時(shí)間小于結(jié)束時(shí)間的條件 Criteria between = Criteria.where("time").gte(beginTime).lte(endTime); criteriaList.add(between); }else{ // 其中一個(gè)為空 分別進(jìn)行判斷 if(beginTime != null){ Criteria gte = Criteria.where("time").gte(beginTime); criteriaList.add(gte); } if(endTime != null){ Criteria lte = Criteria.where("time").lte(endTime); criteriaList.add(lte); } } // 添加狀態(tài)為1條件 if(statue!=null){ Criteria isState = Criteria.where("state").is(statue); criteriaList.add(isState); } // 如果有條件 if(criteriaList.size()>0){ // 集合的個(gè)數(shù)就是數(shù)組的長(zhǎng)度 criteriaArray = new Criteria[criteriaList.size()]; // 遍歷添加到數(shù)組中 for(int i = 0 ; i<criteriaList.size(); i++){ criteriaArray[i] = criteriaList.get(i); } }
這種就可以調(diào)用 mongoTemplate.group(Criteria criteria , String inputCollectionName , GroupBy groupBy , Class<T> entityClass) 方法進(jìn)行分組查詢了
GroupBy groupBy = new GroupBy("分組字段") .initialDocument("{ count: 0 }") .reduceFunction("function (doc,pre){pre.count +=1 ;}"); // new Criteria().andOperator(criteriaArray) 這個(gè)是很關(guān)鍵的一步操作,把剛剛的條件數(shù)組放入進(jìn)入 // groupByResults 這個(gè)對(duì)象里面內(nèi)容很多,有興趣的朋友可以斷點(diǎn)進(jìn)入看一下 GroupByResults groupByResults = mongoTemplate. group(new Criteria().andOperator(criteriaArray), mongodb的collectionName, groupBy, 實(shí)體類.class); // 獲取分組后的數(shù)量 long resultCount = ((List)groupByResults.getRawResults().get("retval")).size();
mongoTemplate分組查詢的坑
Aggregation agg = Aggregation.newAggregation( ? ? ? ? ? ? ? ? Aggregation.match(new Criteria().orOperator(new Criteria("to").is(ukey), new Criteria().and("fromAccount").is(ukey))), ? ? ? ? ? ? ? ? Aggregation.sort(Sort.Direction.DESC,"_id"), ? ? ? ? ? ? ? ? Aggregation.group("to","fromAccount") ? ? ? ? );
Aggregation.group 要排在Aggregation.match后面,否則結(jié)果集不準(zhǔn)確。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
舉例講解Java設(shè)計(jì)模式中的對(duì)象池模式編程
這篇文章主要介紹了Java設(shè)計(jì)模式中的對(duì)象池模式編程示例分享,對(duì)象池模式經(jīng)常在多線程開發(fā)時(shí)被用到,需要的朋友可以參考下2016-02-02Java?Spring?Dubbo三種SPI機(jī)制的區(qū)別
這篇文章主要介紹了Java?Spring?Dubbo三種SPI機(jī)制的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-08-08java實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02聊聊注解@Aspect的AOP實(shí)現(xiàn)操作
這篇文章主要介紹了聊聊注解@Aspect的AOP實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01struts2數(shù)據(jù)處理_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Struts2框架框架使用OGNL語言和值棧技術(shù)實(shí)現(xiàn)數(shù)據(jù)的流轉(zhuǎn)處理。下面通過本文給大家分享struts2數(shù)據(jù)處理的相關(guān)知識(shí),感興趣的朋友參考下吧2017-09-09springboot項(xiàng)目之相互依賴報(bào)錯(cuò)問題(基于idea)
這篇文章主要介紹了springboot項(xiàng)目之相互依賴報(bào)錯(cuò)問題(基于idea),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02