java操作mongodb之多表联查的实现($lookup)
作者:要么出众,要么出局 发布时间:2023-08-08 10:24:07
标签:java,mongodb,多表联查
最近在开发的过程中,一个列表的查询,涉及到了多表的关联查询,由于持久层使用的是mongodb,对这个非关系型数据使用的不是很多,所以在实现此功能的过程中出现了不少问题,现在此做记录,一为加深自己的理解,以后遇到此类问题可以快速的解决,二为遇到同样问题的小伙伴提供一点小小的帮助。
全文分为两部分:
使用robo3t编写多表关系的查询语句
将编写的查询语句整合到java项目
多表联查的查询语句:
此处使用的为mongodb的robo3t可视化工具,先说下需求:从A(假如说是日志表)表中查询出符合条件的数据,根据A表中符合条件数据查询B(假如说是信息表)表中的数据,此处也可以将B表的查询条件加入进来(类型于关系型数据库中的临时表)
mongo查询语句:
db.getCollection('A').aggregate([
{
$lookup:{
from:'B',
localField:'userid',
foreignField:'userid',
as:'userinfo'
}
},
{
$unwind:'$userrole'//把一个数组展成多个,就比如说按多表连查的userrole数组中有10数据,那么用$unwind将把一条带数组的数据分成10条,这10条数据除了userrole不同之外,其它数据都是相同的,就类似于一个展开操作
},
{
$match:{'username':'zhangsan'}
},
{
$group:{
_id:{
userid:'$userid',//这个属性必须是要A表中有的
userrole:'$userrole.roleid',//A表中有一个集合,里面存放的对象有一个名为roleid的属性
},
operateTime:{
$last:'$operateTime'//取A表操作时间最后一条件数
}
info:{
$first:'$userinfo'//因为数组的扩展,造成了大量的重复数据(只有userrole不同),$first是只取最新的一条
}
}
},
{
$sort:{'operateTime':-1}//操作时间倒序,-1:倒序,1:升序
},
{
$skip:0//跳过几条数据,也就是从第几条数据开始取
},
{
$limit:5//每页显示几条数据
}
]);
java代码整合查询语句
//定义分组字段
String[] groupIds = new String[] {"$userid","$userrole.roleid"};
//定义查询条件
Criteria criteria = new Criteria();
//相当于where username = "zhangsan"
criteria.and("username").is("zhangsan");
//相当于 where age not in("15","20")
criteria.and("age").nin("15","20");
//in操作对应的语句
//criteria.and("").in();
//定义排序条件
Sort sort = new Sort(Direction.DESC,"operateTime");
//联合查询总条数,分页用
Aggregation aggregationCount = Aggregation.newAggregation(
Aggregation.match(criteria);//查询条件
Aggregation.group(groupIds);//分组字段
);
//联合查询条件
Aggregation newAggregation = Aggregation.newAggregation(
Aggregation.lookup('B','userid','userid','userinfo'),//从表名,主表联接字段,从表联接字段,别名
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类型的参数
Aggregation.limit(pageSize)
);
//查询
AggregationResults<BasicDBObject> aggregate = mongoTemplate.aggregate(
newAggregation ,"A",BasicDBObject.class//A表,是查询的主表
);
int count = mongoTemplate.aggregate(aggregationCount ,"A",BasicDBObject.class).getMappedResults().size();
//组装分页对象
Page<BasicDBObject> pager = new Page<>(aggregate.getMappedResults(),count,pageSize,pageNumber,page*(pageNumber-1));
//对象转换
将BasicDBObject转换成前面需要的类型.....
来源:https://blog.csdn.net/zhangxianling11/article/details/90371629
0
投稿
猜你喜欢
- Android总体有五大布局:线性布局(LiearLayout): 屏幕垂直或水平方向布局。帧布局(FrameLayout):控件从屏幕左上
- 本文实例演示了Java多线程死锁。分享给大家供大家参考,具体如下:package com.damlab.fz;public class De
- 首先我们看一下hibernate的主配置文件<!DOCTYPE hibernate-configuration PUBLIC &nbs
- C# WPF ListView控件的实例详解C#的WPF作为现在微软主流的桌面程序开发平台,相比过去的MFC时代,有了非常多的不同。本人刚从
- 本文不再对值类型进行讨论,主要讨论一下引用类型。如要看内存值类型的朋友可以看一下前一篇C#之CLR内存原理初探。C#引用类型具体分析如下:先
- 声明类定义类:class MyClass { // 字段、构造函数和 // 方法声明}
- 昨天写this用法总结的时候,突然产生了一个问题,请教别人之后,有了自己的一点认识。还是把它写下来,为大家更好的认识提供一点思路。1)有人写
- 本文实例为大家分享了Java实现点击按钮弹出新窗体的功能,旧窗体不进行操作分析:对于自定义窗体来说,最简单直接的做法就是让新窗体继承java
- 在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能
- 项目结构:效果图一:效果图二:效果图三:关于闹钟:Alarm hongten v1.0 使用说明: &nbs
- 本文实例为大家分享了C#支付宝扫码支付示的具体代码,供大家参考,具体内容如下支付宝工具类using System; using System
- 开发过程中经常遇到需要用某些http://maven.apache.org/中没有的jar包,这个时候可以用maven命令自己添加通常这些j
- 1、添加android support包因为上面的几个类都是在android support包中才提供,我们先添加包。在Eclipse-&g
- 一、登录认证基于过滤器链Spring Security的登录验证流程核心就是过滤器链。当一个请求到达时按照过滤器链的顺序依次进行处理,通过所
- SpringCloud @FeignClient 参数详解今天因为工作中遇到FeignClient一个奇葩的bug,后面仔细研究了,找出了原
- c#开发cad如何预览图块1.定义变量的方法代码如下2. 获取GetDwgImag图像的方法代码3.实现显示DWG文件的方法代码方
- 本文实例讲述了Java使用Random类生成随机数。分享给大家供大家参考,具体如下:一 代码import java.util.Random;
- 1、引入依赖<dependency><groupId>org.springframework.boot</gr
- 主要思想:将一个view设计成多层:背景层,含中奖信息等;遮盖层,用于刮奖,使用关联一个Bitmap的Canvas在该Bitmap上,使用它
- Android中的ListView应该算是布局中几种最常用的组件之一了,使用也十分方便,下面将介绍ListView几种比较常见的优化方法:首