java操作mongodb之多表聯(lián)查的實(shí)現(xiàn)($lookup)
最近在開(kāi)發(fā)的過(guò)程中,一個(gè)列表的查詢,涉及到了多表的關(guān)聯(lián)查詢,由于持久層使用的是mongodb,對(duì)這個(gè)非關(guān)系型數(shù)據(jù)使用的不是很多,所以在實(shí)現(xiàn)此功能的過(guò)程中出現(xiàn)了不少問(wèn)題,現(xiàn)在此做記錄,一為加深自己的理解,以后遇到此類問(wèn)題可以快速的解決,二為遇到同樣問(wèn)題的小伙伴提供一點(diǎn)小小的幫助。
全文分為兩部分:
- 使用robo3t編寫(xiě)多表關(guān)系的查詢語(yǔ)句
- 將編寫(xiě)的查詢語(yǔ)句整合到j(luò)ava項(xiàng)目
多表聯(lián)查的查詢語(yǔ)句:
此處使用的為mongodb的robo3t可視化工具,先說(shuō)下需求:從A(假如說(shuō)是日志表)表中查詢出符合條件的數(shù)據(jù),根據(jù)A表中符合條件數(shù)據(jù)查詢B(假如說(shuō)是信息表)表中的數(shù)據(jù),此處也可以將B表的查詢條件加入進(jìn)來(lái)(類型于關(guān)系型數(shù)據(jù)庫(kù)中的臨時(shí)表)
mongo查詢語(yǔ)句:
db.getCollection('A').aggregate([ { $lookup:{ from:'B', localField:'userid', foreignField:'userid', as:'userinfo' } }, { $unwind:'$userrole'//把一個(gè)數(shù)組展成多個(gè),就比如說(shuō)按多表連查的userrole數(shù)組中有10數(shù)據(jù),那么用$unwind將把一條帶數(shù)組的數(shù)據(jù)分成10條,這10條數(shù)據(jù)除了userrole不同之外,其它數(shù)據(jù)都是相同的,就類似于一個(gè)展開(kāi)操作 }, { $match:{'username':'zhangsan'} }, { $group:{ _id:{ userid:'$userid',//這個(gè)屬性必須是要A表中有的 userrole:'$userrole.roleid',//A表中有一個(gè)集合,里面存放的對(duì)象有一個(gè)名為roleid的屬性 }, operateTime:{ $last:'$operateTime'//取A表操作時(shí)間最后一條件數(shù) } info:{ $first:'$userinfo'//因?yàn)閿?shù)組的擴(kuò)展,造成了大量的重復(fù)數(shù)據(jù)(只有userrole不同),$first是只取最新的一條 } } }, { $sort:{'operateTime':-1}//操作時(shí)間倒序,-1:倒序,1:升序 }, { $skip:0//跳過(guò)幾條數(shù)據(jù),也就是從第幾條數(shù)據(jù)開(kāi)始取 }, { $limit:5//每頁(yè)顯示幾條數(shù)據(jù) } ]);
java代碼整合查詢語(yǔ)句
//定義分組字段 String[] groupIds = new String[] {"$userid","$userrole.roleid"}; //定義查詢條件 Criteria criteria = new Criteria(); //相當(dāng)于where username = "zhangsan" criteria.and("username").is("zhangsan"); //相當(dāng)于 where age not in("15","20") criteria.and("age").nin("15","20"); //in操作對(duì)應(yīng)的語(yǔ)句 //criteria.and("").in(); //定義排序條件 Sort sort = new Sort(Direction.DESC,"operateTime"); //聯(lián)合查詢總條數(shù),分頁(yè)用 Aggregation aggregationCount = Aggregation.newAggregation( Aggregation.match(criteria);//查詢條件 Aggregation.group(groupIds);//分組字段 ); //聯(lián)合查詢條件 Aggregation newAggregation = Aggregation.newAggregation( Aggregation.lookup('B','userid','userid','userinfo'),//從表名,主表聯(lián)接字段,從表聯(lián)接字段,別名 Aggregation.unwind("$userrole"), Aggregation.match(criteria), Aggregation.group(groupIds) .last("$operateTime").as("operateTime")//取值,起別名 .first("$userinfo").as("info"), Aggregation.sort(sort), Aggregation.skip(pageSize*(pageNumber-1L)),//Long類型的參數(shù) Aggregation.limit(pageSize) ); //查詢 AggregationResults<BasicDBObject> aggregate = mongoTemplate.aggregate( newAggregation ,"A",BasicDBObject.class//A表,是查詢的主表 ); int count = mongoTemplate.aggregate(aggregationCount ,"A",BasicDBObject.class).getMappedResults().size(); //組裝分頁(yè)對(duì)象 Page<BasicDBObject> pager = new Page<>(aggregate.getMappedResults(),count,pageSize,pageNumber,page*(pageNumber-1)); //對(duì)象轉(zhuǎn)換 將BasicDBObject轉(zhuǎn)換成前面需要的類型.....
到此這篇關(guān)于java操作mongodb之多表聯(lián)查的實(shí)現(xiàn)($lookup)的文章就介紹到這了,更多相關(guān)java mongodb多表聯(lián)查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解MongoDB中的日志模塊
- MongoDB聚合group的操作指南
- 2021最新版windows10系統(tǒng)MongoDB數(shù)據(jù)庫(kù)安裝及配置環(huán)境
- MongoDB 常用的數(shù)據(jù)類型和基本操作
- MongoDB 簡(jiǎn)單入門(mén)教程(安裝、基本概念、創(chuàng)建用戶)
- MongoDB 主分片(primary shard)相關(guān)總結(jié)
- 詳解MongoDB的角色管理
- MongoDB 監(jiān)控工具mongostat和mongotop的使用
- MongoDB 副本集的搭建過(guò)程
- MongoDB的chunk詳解
相關(guān)文章
細(xì)致解讀希爾排序算法與相關(guān)的Java代碼實(shí)現(xiàn)
這篇文章主要介紹了希爾排序算法與相關(guān)的Java代碼實(shí)現(xiàn),希爾排序的時(shí)間復(fù)雜度根據(jù)步長(zhǎng)序列的不同而不同,需要的朋友可以參考下2016-05-05在spring?boot3中使用native?image的最新方法
這篇文章主要介紹了在spring?boot3中使用native?image?,今天我們用具體的例子來(lái)給大家演示一下如何正確的將spring boot3的應(yīng)用編譯成為native image,需要的朋友可以參考下2023-01-01java中StringBuffer的length()和capacity()方法對(duì)比
這篇文章主要介紹了java中StringBuffer的length()和capacity()方法對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Mybatis在注解上如何實(shí)現(xiàn)動(dòng)態(tài)SQL
這篇文章主要介紹了Mybatis在注解上如何實(shí)現(xiàn)動(dòng)態(tài)SQL,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06java中JVM中如何存取數(shù)據(jù)和相關(guān)信息詳解
這篇文章主要介紹了JVM中如何存取數(shù)據(jù)和相關(guān)信息詳解,Java源代碼文件(.java后綴)會(huì)被Java編譯器編譯為字節(jié)碼文件,然后由JVM中的類加載器加載各個(gè)類的字節(jié)碼文件,加載完畢之后,交由JVM執(zhí)行引擎執(zhí)行。JVM中怎么存取數(shù)據(jù)和相關(guān)信息呢?,需要的朋友可以參考下2019-06-06