基于 MongoTemplate 实现MongoDB的复杂查询

SpringBoot MongoTemplate使用详解 阅读详情

MongoDB是典型的非关系型数据库,但是它的功能越来越复杂,很多项目中,我们为了快速拓展,甚至直接使用Mongo 来替代传统DB做数据持久化。
虽然MongoDB在支持具体业务时没有问题,但是由于它是文档型数据库,拥有一套独立的语法,不再支持传统的SQL。
开发人员发现在实际开发过程中,由于语法问题,在处理复杂的业务查询时,不知该如何下手,使不上劲。
在这里我总结了一下接触到的使用场景:
如果是简单的业务,那么我们直接使用spring JPA来实现就可以,比如这些操作:
1、创建
2、删除
3、修改
4、简单的查询
因为这些语句的逻辑往往不是很复杂,JPA完全可以胜任,而且还清晰直观。
如果是复杂的场景,我们就使用MongoTemplate 来组织条件逻辑:
假设背景是有张Student 表,结构如下:
我们已经预先插入了下边的数据:

(1)先来一个简单的
单条件查询:

1     private void simpleInQuery() {
2         Query query = new Query();
3         query.addCriteria(Criteria.where("classNo").ne(2));
4         List<Student> students = mongoTemplate.find(query, Student.class);
5         log.warn("the query result is: {}", students);
6     }

输出如下:

14:39:19.805  WARN 83348 --- [           main] c.e.demo.learn.mongo.MongodbController   : the query result is: 
[Student(_id=674d8125bf8e9e35bbc08718, name=xiaoa, description=good1, classNo=1, age=15), 
Student(_id=674d8125bf8e9e35bbc08719, name=xiaob, description=good2, classNo=1, age=13), 
Student(_id=674d8125bf8e9e35bbc0871a, name=xiaoc, description=good3, classNo=1, age=15),
Student(_id=674d8125bf8e9e35bbc0871b, name=xiaod, description=good4, classNo=1, age=15), 
Student(_id=674d8153c993425aaa5c4fec, name=zhongd, description=perfect2, classNo=3, age=15), 
Student(_id=674d81dc8130705614f23311, name=biga, description=nice, classNo=3, age=15), 
Student(_id=674d81dd8130705614f23312, name=bigb, description=nice, classNo=3, age=13), 
Student(_id=674d81dd8130705614f23313, name=bigc, description=nice, classNo=3, age=15), 
Student(_id=674d81dd8130705614f23314, name=bigd, description=nice, classNo=3, age=15)]

观察代码,我们发现需要首先创建一个Query 实例,表示是一个查询动作。
query 对象,继续补充一个Criteria 实例。Criteria 英[kraɪ'tɪəriə] 译为比标准、准则、尺度。我们可以直接理解为查询条件。
注意Criteria 实例是由 Criteria.where 方法创建出来的。(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )这是一个简单工厂,参数为要查询的表的列名(文档的字段)。再跟一个in() ,表示列的in 操作,in() 中跟的是in操作的值。
最后直接用mongoTemplate 实例执行find 操作就好,条件为查询逻辑和表对应的类文件。
我们这里使用的是in 操作,除此之外,常用的还有

方法作用类比sql

gt表示 大于>

gte表示 大于等于 >=

lt 表示 小于<

lte 表示 小于等于 <=

ne 表示 不等于 !=

nin 表示 不属于 not in

is 表示等于 =

regex

表示 like (注意后面跟正则表达式,如 "^.*" + queryKeyWord + ".*$")like ‘%关键字%’

这些都是基本操作,有sql经验的同学肯定明白具体怎么使用。
我们再补充一个模糊查询的例子:

1     private void simpleRegexQuery() {
2         Query query = new Query();
3         String queryKeyWord = "ong";
4         query.addCriteria(Criteria.where("name").regex("^.*" + queryKeyWord + ".*$"));
5         List<Student> students = mongoTemplate.find(query, Student.class);
6         log.warn("the query result is: {}", students);
7     }

输出如下:

2024-12-03 14:46:23.781  WARN 81708 --- [           main] c.e.demo.learn.mongo.MongodbController   : the query result is: 
[Student(_id=674d8152c993425aaa5c4fe9, name=zhonga, description=perfect2, classNo=2, age=15), 
Student(_id=674d8153c993425aaa5c4fea, name=zhongb, description=perfect2, classNo=2, age=13), 
Student(_id=674d8153c993425aaa5c4feb, name=zhongc, description=perfect2, classNo=2, age=15), 
Student(_id=674d8153c993425aaa5c4fec, name=zhongd, description=perfect2, classNo=3, age=15)]

(2)接着来看一个相对复杂点的组合条件:
两个或条件,类似于SQL中的: A表达式 OR B表达式,代码如下

 1     private void simpleOrQuery() {
 2         Query query = new Query();
 3         String queryKeyWord = "ong";
 4         Criteria neCri = Criteria.where("age").ne(15);
 5         Criteria regexCri = Criteria.where("name").regex("^.*" + queryKeyWord + ".*$");
 6         Criteria orCri = new Criteria().orOperator(neCri, regexCri);
 7         query.addCriteria(orCri);
 8         List<Student> students = mongoTemplate.find(query, Student.class);
 9         log.warn("the query result is: {}", students);
10     }

执行效果如下:

2024-12-03 14:48:28.787  WARN 83804 --- [           main] c.e.demo.learn.mongo.MongodbController   : the query result is: 
[Student(_id=674d8125bf8e9e35bbc08719, name=xiaob, description=good2, classNo=1, age=13), 
Student(_id=674d8152c993425aaa5c4fe9, name=zhonga, description=perfect2, classNo=2, age=15), 
Student(_id=674d8153c993425aaa5c4fea, name=zhongb, description=perfect2, classNo=2, age=13),
 Student(_id=674d8153c993425aaa5c4feb, name=zhongc, description=perfect2, classNo=2, age=15), 
Student(_id=674d8153c993425aaa5c4fec, name=zhongd, description=perfect2, classNo=3, age=15), 
Student(_id=674d81dd8130705614f23312, name=bigb, description=nice, classNo=3, age=13)]

我们创建好两个Criteria的简单条件之后,再创建一个新的Criteria 实例,用一个or操作将二者关联起来.
query 接收最新的Criteria 实例,然后执行查询即可。
这里的写法类似于sql中的
where name like "%ong%" or age != 15

如果是两个AND 条件,类似于SQL中的: (防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )A表达式 AND B表达式,用法和or的使用方法是一样的 。这里就不举例了,
我们这里写一个复杂的用法:

 1     private void complexQuery() {
 2         Query query = new Query();
 3 
 4         String queryKeyWord = "ong";
 5         Criteria ageCri = Criteria.where("age").ne(15);
 6         Criteria nameCri = Criteria.where("name").regex("^.*" + queryKeyWord + ".*$");
 7         Criteria cri1 = new Criteria().orOperator(ageCri, nameCri);
 8 
 9         Criteria descCri = Criteria.where("description").is("nice");
10         Criteria classNoCri = Criteria.where("classNo").in(1, 2, 3);
11         Criteria cri2 = new Criteria().andOperator(descCri, classNoCri);
12 
13         query.addCriteria(new Criteria().orOperator(cri1, cri2));
14         List<Student> students = mongoTemplate.find(query, Student.class);
15         log.warn("the query result is: {}", students);
16     }

输出如下:

2024-12-03 14:51:46.908  WARN 92840 --- [           main] c.e.demo.learn.mongo.MongodbController   : the query result is: 
[Student(_id=674d8125bf8e9e35bbc08719, name=xiaob, description=good2, classNo=1, age=13), 
Student(_id=674d8152c993425aaa5c4fe9, name=zhonga, description=perfect2, classNo=2, age=15), 
Student(_id=674d8153c993425aaa5c4fea, name=zhongb, description=perfect2, classNo=2, age=13), 
Student(_id=674d8153c993425aaa5c4feb, name=zhongc, description=perfect2, classNo=2, age=15), 
Student(_id=674d8153c993425aaa5c4fec, name=zhongd, description=perfect2, classNo=3, age=15), 
Student(_id=674d81dc8130705614f23311, name=biga, description=nice, classNo=3, age=15), 
Student(_id=674d81dd8130705614f23312, name=bigb, description=nice, classNo=3, age=13), 
Student(_id=674d81dd8130705614f23313, name=bigc, description=nice, classNo=3, age=15),
 Student(_id=674d81dd8130705614f23314, name=bigd, description=nice, classNo=3, age=15)](防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )

这里的写法类似于sql中的

where ( description = "nice" and classNo in (1 ,2 ,3) ) or ("name like %ong%" or age != 15)

总体来看:一个Criteria 实例,就是一个查询条件。

我们可以通过 or、and 操作来不断的组合生成一个新的Criteria实例,也就是一个新的查询条件 ,并且可以以此查询条件继续组合生成更高级的Criteria,以此不断的类推。

这个过程就像垒积木一样:

(3) 接着我们整合下分页功能,并且以班级排序

PageRequest pageable = PageRequest.of(pageIndex - 1, pageSize);
Query pageQuery=query.with(pageable).with(Sort.by(Sort.Direction.DESC,"classNo"));

注意分页时,页码数是从0开始,所以要-1。同时排序使用Sort生成sort的对象,包含排序方式和字段,并且这里支持多级排序。

整体代码如下:

 1     private void complexPageQuery() {
 2         int pageIndex=2;
 3         int pageSize=3;
 4         Query query = new Query();
 5         String queryKeyWord = "ong";
 6         Criteria ageCri = Criteria.where("age").ne(15);
 7         Criteria nameCri = Criteria.where("name").regex("^.*" + queryKeyWord + ".*$");
 8         Criteria cri1 = new Criteria().orOperator(ageCri, nameCri);
 9 
10         Criteria descCri = Criteria.where("description").is("nice");
11         Criteria classNoCri = Criteria.where("classNo").in(1, 2, 3);
12         Criteria cri2 = new Criteria().andOperator(descCri, classNoCri);
13 
14         query.addCriteria(new Criteria().orOperator(cri1, cri2));
15         long allDataSize = mongoTemplate.count(query, Student.class);
16         PageRequest pageable = PageRequest.of(pageIndex - 1, pageSize);
17         Query pageQuery=query.with(pageable).with(Sort.by(Sort.Direction.DESC,"classNo"));
18         List<Student> students = mongoTemplate.find(pageQuery, Student.class);
19         log.warn("the query result is: {}", students);
20     }

输出如下:

2024-12-03 14:56:46.059  WARN 18516 --- [           main] c.e.demo.learn.mongo.MongodbController   : the query result is: 
[Student(_id=674d81dd8130705614f23314, name=bigd, description=nice, classNo=3, age=15),
 Student(_id=674d81dc8130705614f23311, name=biga, description=nice, classNo=3, age=15), 
Student(_id=674d8152c993425aaa5c4fe9, name=zhonga, description=perfect2, classNo=2, age=15)]

[官方培训]22-UE资产优化 Epic 肖月 笔记 Nanite+Lumen目标:面向TA,美术,不影响视觉的前提下,优化运行和编辑效率引擎:UE5.1延迟管线平台:主流PC,Windows 10 with DX12。 阅读详情

相关推荐

Rstudio安装org.Hs.eg.db

自己也是个小白,初次安装org.Hs.eg.db碰到好多问题,步骤总结如下: 第一,instal.packages()安装,不行则换 BiocManager::install() 第二,如BiocManager不成,说明不是最新版本,可按提示安装最新版 BiocManager::install(version = '3.13') #由于R版本较新,按照提示中的相关信息,安装最新版本的 第三,再次安装 BiocManager::install("org.Hs.eg.db") 第四,之后每个人.

ZH_DDong的博客 2万+

MongoTemplate 常用查询

是Spring Data MongoDB提供的一个Java编程接口,用于操作MongoDB数据库。它提供了一系列方法和功能,以便进行数据的插入、更新、删除和查询等操作。使用MongoTemplate,你可以通过编写Java代码与MongoDB进行交互,而无需直接编写原生的MongoDB查询语句。它提供了一些便捷的方法,如save、insert、update和remove,用于对文档进行增删改操作。同时,它还支持复杂的查询条件和排序,以及聚合管道查询等高级功能。

CentOS 1959

头歌操作系统2023春季课堂练习2.1:外部中断

本关任务:通过相关知识以及实验回答:版本 1 内核的第 6 次时钟中断发生时,断点和恢复点(指令地址)分别是多少?回答问题:当第一行 0/1 字符全部输出完毕的时候一共发生了几次时钟中断,即第一行完全填满时 jiffies 记录的已发生次数为多少?本关任务:通过实际操作回答在输出第一行 0/1 字符的过程中(如下图所示),共发生了几次时钟中断?2.此时 bochs 虚拟机输出的 0/1 字符串是什么?(只填写数字,不填写空格!根据相关知识进行实际操作,一直输入 c 直到 0/1 将第一行完全填满。

weixin_64821608的博客 8129

Java使用MongoTemplate实现多条件、模糊查询、排序、范围、分页查询

MongoTemplate实现复杂条件查询

Java_Rookie_Xiao的博客 9988

经纬度转换为UTM坐标

UTM(通用横向墨卡托投影): 是一种以米为单位的坐标系统,用于地图和GPS导航。将地球划分为60个纵向的区域。每个区域宽6度,从赤道开始往南北两级方向划分。每个区域都有一个特定的字母。

weixin_45626706的博客 7275

浙大数值分析lab2

最可怕的一道题,题目是这样的 Root of a Polynomial A polynomial of degree nnn has the common form as p(x)=cnxn+cn−1xn−1+⋯+c1x+c0p(x)=c_n x^n + c_{n-1} x^{n-1} + \cdots + c_1 x + c_0p(x)=c​n​​x​n​​+c​n−1​​x​

yao_zou的博客 4797

mongoTemplate查询

//设置分页 Integer pageSize = po.getPageSize(); Integer startRows = (po.getPage() - 1) * pageSize; //模糊查询 Criteria criteria = new Criteria(); if (!StringUtils.isEmpty(po.getKeyword())){ String regex = String.format("%s%s%s", “^.", po.getKeyword().trim(), ".$”)

weixin_44405111的博客 1516

告别命令行恐惧!用TBtools的MCScanX插件,5分钟搞定拟南芥和水稻的基因组共线性分析

本文介绍如何利用TBtools的MCScanX插件快速完成拟南芥和水稻的基因组共线性分析,无需命令行操作,5分钟即可生成专业可视化结果。通过图形化界面简化传统MCScanX的复杂流程,特别适合非生物信息背景的研究者,显著提升基因组数据分析效率。

dianzhuique8587的博客 377

Spring Data MongoDB--MongoTemplate查询数据--方法/实例

本文用示例介绍Spring Data MongoDB(MongoTemplate)查询数据的方法。

IT利刃出鞘的博客 4574

黏菌优化算法(SMA)详解:从生物智能到优化引擎

黏菌优化算法(SMA)是一种新型生物启发式优化算法,模拟多头绒泡菌的智能觅食行为。该算法包含接近食物、包围食物和抓取食物三个阶段,通过数学模型将生物行为转化为优化过程。SMA采用权重自适应机制和参数振荡模型实现探索与开发的平衡,具有参数简单、收敛性好等优势。算法可通过MATLAB/Python实现,并应用于函数优化、工程设计和神经网络训练等领域。研究表明SMA在求解复杂优化问题时表现优异,未来可通过混沌增强、混合策略等方式进一步提升性能。

qq_42212808的博客 659

YOLOv11改进 | Conv/卷积篇 | 轻量化多尺度异构卷积(MSHC)优化YOLOv11精度(全网独家首发)

本文介绍了Hype-YOLO提出的MANet结构,这是C3、C2f、C3k2的升级版,能显著增强特征提取能力。MANet整合了DSConv和C2f结构,通过多分支异构设计提升梯度流动和特征语义深度。文章详细解析了MSHC模块的原理,包括其多尺度并行建模、通道混洗等核心机制,并提供了完整的代码实现和训练教程。实验表明,Hype-YOLO的精度优于YOLOv11。该结构在保持轻量化的同时,通过异构分支设计实现了更丰富的特征表达,适用于目标检测等视觉任务。

Snu77的博客 952

mongoTemplate通过Query条件指定查询条件和返回字段

本文转自Spring Data MongoDB 基本文档查询(Query、BasicQuery),仅做学习备份,如有侵权请联系博主删除! 一.简介 Spring Data MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作。 我们回顾一下,我们在之前介绍了MongoD...

YHJ 7100

海思图像质量之HiPQTool调试

文章目录一. HiPQTool 界面二. 图像调试三. 将调试参数写入程序中 一. HiPQTool 界面 二. 图像调试 三. 将调试参数写入程序中

lzg2011的博客 2381

mongodb跨集合查询_SpringBoot整合MongoDB,使用mongoTemplate实现高级查询

一、前言最近项目使用MongoDB作为数据主要存取的地方又是第一次接触MongoDB,也是踩了不少坑...维护数据无非就是增删改查,而里面最复杂的就是查询了所以来总结一下有关MongoDB的查询方法当然如果你在此之前你对MongoDB一点都不了解的话个人建议点击这里,花三十分钟初步了解一下MongoDBok,正文开始二、正文1.使用mongoTemplate对象常常会调用如下两种方法 ① fin...

weixin_39995764的博客 712

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

MongoDB 查询方式

两种查询方式: 1、JPA 2、MongoTemplate 一、JPA 首先是JPA的 简单查询 dao层 public interface DogRepository extends MongoRepository<Dog,String> { List<Dog> findByName(String name); List<Do...

用针戳左手中指指头的博客 542

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

第十二章 springboot + mongodb(复杂查询)

简单查询:使用自定义的XxxRepository接口即可。(见 第十一章 springboot + mongodb(简单查询)) 复杂查询:使用MongoTemplate以及一些查询条件构建类(BasicDBList、BasicDBObject、Criteria等) 1、application.properties 1 #mongodb note:mongo3.x will ...

weixin_33795833的博客 324

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SpringBoot之MongoTemplate的各种条件查询

SpringBoot之MongoTemplate的各种条件查询 /** * 指定field查询 */ public void specialFieldQuery() { Query query = new Query(Criteria.where("user").is("用户名blog")); // 查询一条满足条件的数据 Map result = mongoTemplate.findOne(query, Map.class

hins 9447

MongoDB结构文档多层次查询及更新

本文记录Spring Data Mongodb中对mongoDB查询及更新的实现. 使用场景 mongoDB中文档会具有较深的深度,在通过mongoTemplate进行处理时,需要注意使用的语法.本文介绍两种场景:深层次查询及更新 技术点 mongoDB语法 mongoTemplate接口API mongoDB文档展示 { "_id" : ObjectId("5d5684ae1599021e848d6736"), "vehicleId" : "AP_4028b2b64fb206970

随心所鱼的博客 3175

mongodb和mongoTemplate复杂条件查询 (or与and)

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/tjbsl/article/details/80620303 使用Mongodb查询需要拼接复杂的or和and参数 MongoDb有表格: 1 "state1" : 11, "state2" : 21, "va...

qq_35568099的博客 1万+

使用MongoDB关联查询

使用MongoDB关联查询使用MongoDB关联查询Mongo shell 关联查询$lookup 简单教程$lookup 示例功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 使用MongoDB关联查询 在工作中,我们有时会使用M

19:30的博客 6347

Spring Boot中使用mongo的复杂查询查找实体中List「T」中的某个属性

Spring Boot中使用mondo的复杂查询查找实体中List中的某个属性 在Spring Boot中使用mongodb数据库来进行增删改查操作,一般在Dao层使用MongoRepository来进行一些基础的增删改查,也可以自己根据MongoRepository提供的方法来写一些需要的增删改查操作。例如findFirstById、findByClassificationsIn、findAllByAuthor等。 但是如果需要判断的条件位于查找实体的List字段中,例如: public class Da

myl_0808的博客 1586

[数据库]MongoTemplate之分组分页复合条件查询

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.youkuaiyun.com/u013487548/article/details/78027851 mongodbsql 文档地址:https://docs.mongodb.com/manual/reference/operator/update/ 废话不多说,直...

varyall的专栏 1945

java实现mongodb的分页排序查询

mongodb的分页排序查询与jpa的类似,使用springdata中提供的接口就可以实现,直接上代码: public Page<User> selUsersSortAndPage(Integer pageNum,Integer size,String userName){ //userName为传入的查询条件,也可以以对象的形式传入多个查询条件 BasicDBOb...

不试一下你怎么知道自己有多强?最不像程序员的程序员的专栏 4271

Spring Boot集成MongoDB,基于MongoRepository与MongoTemplate操作MongoDB

Spring Boot集成MongoDB,基于MongoRepository与MongoTemplate操作MongoDB

积跬步,至千里。 870

MongoDB mongoTemplate查询条作组合例子

[b]MongoDB mongoTemplate查询条作组合例子[/b] [b]常规查询[/b] [code="java"]public DeviceOnlineStatisticsModel findByKeyAndTimeDateMax(String key) { Sort sort = new Sort(new Order(Direction.DESC, "timeDate"...

jie310600的博客 1124
上一篇: MySQL的两阶段提交是什么?它是如何工作的?
下一篇: 2000道面试必问的Java面试八股文及答案整理(2025版)
退休的汤姆
博客等级 码龄7年 1657粉丝 1051原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值