当前位置: 首页 > news >正文

springboot mongo 使用

nosql对我来说,就是用它的变动列,如果列是固定的,我为什么不用mysql这种关系型数据库呢?

所以,现在网上搜出来的大部分,用实体类去接的做法,并不适合我的需求。

所以,整理记录一下,我收集到的springboot,自由,使用mongo的信息。

目录

前置

依赖引入

配置

代码引入

使用

插入

单行插入

批量插入

查询

查询全部(无条件)

条件查询

排序

 DBObject更加自由的查询

聚合

某些列有值,并且只返回选中的列,并且聚合

其他工具包,像客户端一样写查询

mongodb的java驱动MongoClient


前置

依赖引入

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

版本就根据自己的spring版本来好了,不需要额外加

配置

spring.data.mongodb.uri=mongodb://localhost:27017/myTest

我用的本地版本的mongo,没配用户名+密码,如果配了,就需要加下。

本地mongodb的安装,我使用了菜鸟 MongoDB 安装介绍,并安装了mongoDB compass客户端,用来直连查看mongodb里的数据库数据

代码引入

@Resource private MongoTemplate template;

上述配置完成后,直接依赖注入,就可以使用了

使用

插入

单行插入
template.insert(singleObject, "multi_1242");

上述代码中 

singleObject 为 json字符串 {"_id": 3, "1": "1.1", "2": "2.1", "amount": 2.1}

"multi_1242" 为集合名称,我的需求是,不同的集合,里面document的键名,是会完全不同的

批量插入
boolean product = template.collectionExists("multi_1242");if (!product) {template.createCollection("multi_1242");}Gson gson = new Gson();JsonObject jsonObject = new JsonObject();jsonObject.addProperty("_id", 1);jsonObject.addProperty("1", "1.1");jsonObject.addProperty("2", "2.2");jsonObject.addProperty("amount", 10.12);// template.save(gson.toJson(jsonObject), "multi_1242");JsonObject jsonObject1 = new JsonObject();jsonObject1.addProperty("_id", 2);jsonObject1.addProperty("1", "1.2");jsonObject.addProperty("2", "2.2");jsonObject1.addProperty("3", "3.1");jsonObject1.addProperty("amount", 1.13);// template.save(gson.toJson(jsonObject1), "multi_1242");List<String> list = new ArrayList<>();list.add(gson.toJson(jsonObject));list.add(gson.toJson(jsonObject1));template.insert(list, "multi_1242");

这里我使用了google的Json化的工具包,我没有使用ali的fastjson,是因为它的JSON对象转JSON字符串曾经坑过我(它会把一些特殊字符,转换成别的字符)

<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.10.1</version>
</dependency>
import com.google.gson.Gson;
import com.google.gson.JsonObject;

上述动作完成插入后,mongo那边显示的结果为

 从上述的实验,可以得出几个结论

1、springboot插入mongo的话,也是用json字符串去插入的,我曾经试过,直接用jsonObject类型去插入,document查出来,会有很多不需要的字段都被插进去了(这并不是我想要的),所以你想插入什么样子,就组装成什么样子后,json字符串后,再传入进去。下图为错误示范。

2、_id这个键,是默认的主键名称,如果你想控制主键多少,可以设置后,再进行插入

查询

查询全部(无条件)
Query query = new Query();
List<String> list = template.find(query, String.class, "multi_1242");//查看测试结果
LoggerUtils.info("size is " + list.size());
for (int i = 0; i < list.size(); i++) {//使用了封装类,打印了一下查出来的结果LoggerUtils.info(i + " is " + list.get(i));
}

不需要传入查询条件,传个空的query进去就行了

下图为输出结果

条件查询

2个and的查询条件

Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("1").is("1.1");
criteria.and("2").is("2.1");
query.addCriteria(criteria);
List<String> list = template.find(query, String.class, "multi_1242");

查询结果

如果有的document缺少查询条件里的一些键呢,结果是如何呢? 然后我增加了一个查询条件

Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("1").is("1.1");
criteria.and("2").is("2.1");
//增加一条查询条件
criteria.and("3").is("3.1");
query.addCriteria(criteria);
List<String> list = template.find(query, String.class, "multi_1242");

 结果是没有查出来,如果写在where里,明确某个键=某个值的话,那么查出来的document,必然是有该键的。

但是order却不一定,为此,我多插了一行{"_id": 4, "1": "1.1", "2": "2.1","3": "3.1", "amount": 2.1}

排序
Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("1").is("1.1");
criteria.and("2").is("2.1");
query.addCriteria(criteria);
//增加一条排序条件
query.with(Sort.by("3"));
List<String> list = template.find(query, String.class, "multi_1242");

结果

可以看到order依赖的属性不存在,也是可以被查出来的,并且正常排序还排在前面

 DBObject更加自由的查询

上述用这个Query类构造还是束手束脚的,不过我又查到了,跟客户端类似的方法

DBObject obj = new BasicDBObject();
obj.put("1", "1.1");
obj.put("2", "2.1");
Query query = new BasicQuery(obj.toString());
List<String> list = template.find(query, String.class, "multi_1242");

仿照着写,查询结果是ok的

 如果是复杂的查询,可以自己用DBObject,BasicDBList构造嵌套起来

聚合

某些列有值,并且只返回选中的列,并且聚合

如果是客户端的话,可以先过滤出来后,再进行聚合

例如,我想找到“1”列,“2”列有值,并且根据这两列进行合并的,并且返回的结果只包含这2列作为_id,意味着,如果有(1.1,2.1,3.1)和(1.1,2.1)的组合,将会合并到一起

db.multi_1242.aggregate([
#先过滤一波需要的数据
{$match:
{
"1":{$exists:true},
"2":{$exists:true}
}
},
#然后进行合并,_id使用要合并的字段组成
# mytotal这个键是我随便起的,就是group后面跟的对象,就是将会输出的数据格式
{$group:
{
_id:{"1":"$1","2":"$2"},
mytotal:{$sum:"$amount"}
}
}
])

原始数据如图

查询后的结果如下

 

 可以看到我的_id设置的只有“1”列和“2”列,所以合并也是根据我的要求来合的。

如果我的_id加入了“3”列,那么,有的document行有3这个键值,有的没有,又该如何?

查询如下:

可以发现,有“3” 列的就有,没有“3”列的,就没有。

客户端是这样,那么如何在项目中使用聚合来查询?

Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(new Criteria().where("1").is(obj1).and("2").is(obj1)),Aggregation.group("1", "2").sum("amount").as("mytotal"));
AggregationResults results = template.aggregate(aggregation, "multi_1242", String.class);
List<String> mappedResults = results.getMappedResults();

打印得到的结果

这个group查多组合,需要传 Fields

import org.springframework.data.mongodb.core.aggregation.Fields;DBObject obj1 = new BasicDBObject();
obj1.put("$exists", true);Fields fields = Fields.fields("1");
fields = fields.and("2");
fields = fields.and("3");
Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(new Criteria().where("1").is(obj1).and("2").is(obj1)),Aggregation.group(fields).sum("amount").as("mytotal"));
AggregationResults results = template.aggregate(aggregation, "multi_1242", String.class);
List<String> mappedResults = results.getMappedResults();

查询结果

 这个Fields还真是难造,看了下源码,才知道怎么造出来。

然后,如果不想调用各种聚合函数,比如sum,count也是可以的。

比如我把上面的聚合查询,改为这样。

Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(new Criteria().where("1").is(obj1).and("2").is(obj1)),Aggregation.group(fields));

结果如下

 只会查出聚合的键,这也是我需要的内容

其他工具包,像客户端一样写查询

mongodb的java驱动MongoClient

mongoClient的参考文章

其中的这种写法,我是比较赞赏的,因为都是字符串拼接,很自由,引用一下。

Document match = Document.parse("{$match:{$or:[{\"组织机构代码\":\"" + id + "\"}, {\"单位名称\":\"" + id + "\"}]}}");
Document unwind = Document.parse("{$unwind:\"$公司人员\"}");
Document group = Document.parse("{$group : {_id : \"$公司人员." + arrayFiled + "\", count : {$sum : 1}}}");List<Document> conditions = new ArrayList<>();
conditions.add(match);
conditions.add(unwind);
conditions.add(group);List<Document> result = new ArrayList<>();
AggregateIterable<Document> resultSet = this.collection.aggregate(conditions);
try (MongoCursor<Document> cursor = resultSet.iterator()) {while (cursor.hasNext()) {Document item_doc = cursor.next();result.add(item_doc);}
}

Bson的话,两种工具包好像都可以进行使用,我这边就不赘述了。

相关文章:

springboot mongo 使用

nosql对我来说&#xff0c;就是用它的变动列&#xff0c;如果列是固定的&#xff0c;我为什么不用mysql这种关系型数据库呢&#xff1f; 所以&#xff0c;现在网上搜出来的大部分&#xff0c;用实体类去接的做法&#xff0c;并不适合我的需求。 所以&#xff0c;整理记录一下…...

如何使用appuploader制作apple证书​

转载&#xff1a;如何使用appuploader制作apple证书​ 如何使用appuploader制作apple证书​ 一.证书管理​ 点击首页的证书管理 二.新建证书​ 点击“添加”&#xff0c;新建一个证书文件 免费账号制作证书只有7天有效期&#xff0c;没有推送消息功能&#xff0c;推送证书…...

Promise详细版

promise基础原理到难点分析 常见的Promise的方法解读 扩展async和await深入分析 逐步分析Promise底层逻辑代码 一、Promise基础 1.什么是promise 为了解决回调地狱&#xff1a; //2.设置点击事件btn.onclick function() {//3.创建ajax实例化对象let xhr new XMLHttpRe…...

v-for循环生成的盒子只改变当前选中的盒子的样式

1.给盒子添加动态属性:class"[index isActive?active-box:choose-box]" <div v-for"(item,index) in zyList" :key"item.sid" :class"[index isActive?active-box:choose-box]" click"getKmList(item,index)"…...

Spring Data JPA源码

导读: 什么是Spring Data JPA? 要解释这个问题,我们先将Spring Data JPA拆成两个部分&#xff0c;即Sping Data和JPA。 从这两个部分来解释。 Spring Data是什么? 摘自: https://spring.io/projects/spring-data Spring Data’s mission is to provide a familiar and cons…...

如何防止CSRF攻击

背景 随着互联网的高速发展&#xff0c;信息安全问题已经成为企业最为关注的焦点之一&#xff0c;而前端又是引发企业安全问题的高危据点。在移动互联网时代&#xff0c;前端人员除了传统的 XSS、CSRF 等安全问题之外&#xff0c;又时常遭遇网络劫持、非法调用 Hybrid API 等新…...

linuxARM裸机学习笔记(7)----RTC实时时钟实验

基础概念&#xff1a; I.MX6U 内部也有个RTC 模块&#xff0c;但是不叫作“ RTC ”&#xff0c;而是叫做“ SNVS ”。 SNVS 直译过来就是安全的非易性存储&#xff0c; SNVS 里面主要是一些低功耗的外设&#xff0c;包括一个 安全的实时计数器 (RTC) 、一个单调计数器 (mo…...

NSS [UUCTF 2022 新生赛]ez_upload

NSS [UUCTF 2022 新生赛]ez_upload 考点&#xff1a;Apache解析漏洞 开题就是标准的上传框 起手式就是传入一个php文件&#xff0c;非常正常的有过滤。 .txt、.user.ini、.txxx都被过滤了&#xff0c;应该是白名单或者黑名单加MIME过滤&#xff0c;只允许.jpg、.png。 猜测二…...

【操作系统】操作系统知识点总结(秋招篇)

文章目录 前言操作系统主要做了哪些工作&#xff1f;进程 线程 协程之间的区别进程的组成部分介绍一下进程的PCB讲一下进程的五态 以及它们的状态转移用户态和内核态是什么&#xff1f;进程在用户态和内核态之间是如何切换的讲一下进程之间的通信方式讲一下进程调度的三个层次介…...

篇十九:迭代器模式:遍历集合

篇十九&#xff1a;"迭代器模式&#xff1a;遍历集合" 开始本篇文章之前先推荐一个好用的学习工具&#xff0c;AIRIght&#xff0c;借助于AI助手工具&#xff0c;学习事半功倍。欢迎访问&#xff1a;http://airight.fun/。 另外有2本不错的关于设计模式的资料&…...

浅谈JVM中的即时编译器(Just-In-Time compiler, JIT)

Java虚拟机&#xff08;JVM&#xff09;中的即时编译器&#xff08;Just-In-Time compiler, JIT&#xff09;是一个非常重要的组件&#xff0c;它负责将字节码转换为本地机器代码。在不使用JIT的情况下&#xff0c;JVM通过解释字节码来执行程序&#xff0c;这意味着它会为每个字…...

Android 13 Launcher——长按图标弹窗内容修改以及小组件等隐藏起来

目录 一.背景 二.实现思路 三.布局文件修改 四.隐藏代码中原先的view 一.背景 由于定制化开发需要将原先的长按图标原生弹窗界面隐藏,然后显示自定义的弹窗界面,如下就是我们来实现自定义的弹窗界面...

又一个不可错过的编程大模型来了让你惊呼“码农人生”不虚此行

继Stable Diffusion爆火之后&#xff0c;StabilityAI近期又放大招&#xff0c;推出了号称是革命性的编程大模型StableCode。StableCode是其首款用于编码的LLM生成式AI产品&#xff0c;该产品旨在帮助程序员完成日常工作。目前已发布的版本为StableCode-Completion-Alpha-3B&…...

【Express.js】集成SocketIO

集成SocketIO 本节我们介绍在如何在 express 中集成 Socket.IO Socket.IO 算是 WebSocket 的一个超集&#xff0c;进行了一些封装和拓展。 准备工作 创建一个 express.js 项目&#xff08;本文基于evp-express-cli&#xff09;安装socket.io.js: npm i socket.io创建代理 …...

为树莓派Pico配置交叉编译环境和工具链arm-none-eabi-gcc时可能会遇到的错误以及解决方案

本文是一个类似手册的文章&#xff0c;用来记录可能遇到的错误。你可以通过侧栏选择遇到的错误来查看详细信息。 No install step for ‘ELF2UF2Build’ 遇到这种错误有两种原因&#xff1a; 安装了版本不对或者不完整的arm-none-eabi-gcc&#xff1b;没有使用正确的 C/C 的…...

Yum 部署K8S集群

目录 1、准备环境 &#xff08;温馨提示&#xff1a;尽量一次完成集群&#xff09; 2.安装master节点 3、安装k8s-master上的node 4、安装配置k8s-node1节点 5、安装k8s-node2节点 6、为所有node节点配置flannel网络 7、配置docker开启加载防火墙规则允许转发数据 一. 环…...

初阶C语言-操作符详解(下)

&#x1f31e; “等春风得意&#xff0c;等时间嘉许&#xff01;” 接下来&#xff0c;我们把操作符没学完的继续学完&#xff01; 操作符详解 6.2sizeof和数组 7.关系操作符8.逻辑操作符9.条件操作符10.逗号表达式11.下标引用、函数调用和结构成员12.表达式求值12.1隐式类型转…...

reposync命令——下载yum仓库中全部的包到本地

reposync命令可以将远端yum仓库里面的包全部都下载到本地。这样构建自己的yum仓库&#xff0c;就不会遇到网络经常更新包而头疼的事情了。 reposync命令在软件包 yum-utils 里面&#xff0c;需要保证yum-utils已安装。 yum install yum-utils -y 常用参数 -r &#xff1a;指定…...

LC-杨辉三角

LC-杨辉三角 链接&#xff1a;https://leetcode.cn/problems/pascals-triangle/submissions/ 上图就是一个杨辉三角&#xff0c;每个数等于他左上角的数与右上角的数之和。 第一行就是一个1&#xff1b;第二行是两个1&#xff1b;第三行的2就是它肩膀上两个1之和,其余的类似。…...

Golang空结构体struct{}的作用是什么?

文章目录 占位符&#xff1a;通道标识&#xff1a;键集合&#xff1a;内存占用优化&#xff1a;总结&#xff1a; 在Go语言中&#xff0c;空结构体 struct{}是一种特殊的数据类型&#xff0c;它不占用任何内存空间。空结构体没有任何字段&#xff0c;也没有任何方法。尽管它看起…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...