MongoDB


MongoDB

#author:编程不良人
https://www.bilibili.com/video/BV1vL4y1J7i3?from=search&seid=124111734526738029&spm_id_from=333.337.0.0
image-20220320002939870

一、简介

  • 文档地址

    https://docs.mongodb.com/manual/
  • 官方

    MongoDB是一个非关系型文档数据库,旨在方便应用开发和扩展

    image-20220320224633606
  • 百度百科

    MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展高性能数据存储解决方案。

    MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最想关系数据库的。

    MongoDB支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。

    MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似于关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

  • bson

    BSON( Binary Serialized Document Format) 是一种二进制形式的存储格式,采用了类似于 C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的特点,可以有效描述非结构化数据和结构化数据。

    对比关系数据库,一条记录对应数据库某张表的一行;而MongoDB一条记录对应库下面某个集合的一条文档。

    如果现在要存储一个人基本信息和个人爱好,如果用关系数据库记录,则需要用个人基本信息表和个人爱好两张表,如果用MongoDB来存储,只需要通bson格式,一条记录(文档)即可存取。

  • 历史

    1. 2009年2月,MongoDB数据库首次在数据库邻域亮相,打破了关系数据库一统天下的局面;
    2. 2010年8月,MongoDB1.6发布。这个版本最大的功能就是Sharding,自动分片;
    3. 2014年12月,MongoDB3.0发布。由于收购了WiredTiger存储引擎,大幅度提升了MongoDB的写入性能;
    4. 2015年12月,3.2版本发布。开始支持关系型数据库的核心功能:*关联。可以一次同时查询多个MongoDB的集合;
    5. 2016年,MongoDB推出Atlas,在AWS、Azure和GCP上的MongoDB托管服务;
    6. 2017年10月,MongoDB成功在纳斯达克敲钟,成为26年来第一家以数据库产品为主要业务的上市公司;
    7. 2018年6月,MongoDB4.0发布推出ACID事务支持,成为第一个支持强事务的NoSQL数据库;
    8. 2018年至今,MongoDB已经从一个在数据库领域籍籍无名的’小透明‘,变成了话题度和热度都很高的“流量”数据库;

二、特点

  • 特点介绍
    1. 面向集合存储,易存储对象类型的数据;
    2. 支持查询,以及动态查询;
    3. 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言;
    4. 文件存储格式为BSON(一种JSON的扩张);
    5. 支持复制和故障恢复和分片;
    6. 支持事务(目前只在单条文档上支持)
    7. 支持索引(增快查询速率)和聚合(统计和分析)和关联查询;
  • 应用场景
    1. 游戏应用:使用云数据库MongoDB作为游戏服务器的数据库存储用户信息。用户的游戏装备、积分等直接以内嵌文档的形式存储,方便进行查询和更新;
    2. 物流应用:使用云数据库MongoDB存储订单信息,订单状态在运送过程中会不断更新,以云数据库MongDB内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来,方便快捷且一目了然;
    3. 社交应用:使用云数据库MongoDB存储用户信息以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。并且,云数据库MongoDB非常适合用来存储聊天记录,因为它提供了非常丰富的查询,并且在写入和存取方面都相对较快;
    4. 视频直播:使用云数据库MongoDB存储用户信息、礼物信息等;
    5. 大数据应用:使用云数据库MongoDB作为大数据的云存储系统,随时进行数据提取分析,掌握行业动态。

三、安装

1、传统安装

#1、下载MongoDB
https://www.mongodb.com/try/download/community
image-20220321001636348
#2、将下载安装包上传到linux系统
命令:
	tar -zxf mongodb-linux-aarch64-ubuntu2004-5.0.5.tgz
image-20220321002048741
#3、查看安装目录
命令:
	ls
说明:
	bin目录:用来存放启动mongodb的服务以及客户端链接的脚本文件
image-20220321004344094
#4、启动mongodb服务
命令:
	./mongod --port=27017 --dbpath=../data --logpath=../logs/mongo.log
说明:(下面的不一定要指定,都有默认,当前提路径得存在)
    --port:   指定服务监听端口号 默认为27017
    --dbpath: 指定mongodb数据存放目录 启动要求目录必须存在
    --logpath:指定mongodb日志文件存放位置
注意:
	由于启动时指定了日志文件,因此启动时日志输出到日志终端不显示任何日志
image-20220321003639024
#5、客户端连接
命令:
	./mongo --port=27017
image-20220321010120771

2、docker安装

关于docker使用我们可以到 dockerhub 上去查看需要拉取的镜像

https://registry.hub.docker.com/
image-20220321011747729
#1、拉取mongodb镜像
命令:
	docker pull mongo:5.0.5
image-20220321013056820
#2、运行mongo镜像
命令:
	docker run -d  --name mongo --p 27017:27017 mongo:5.0.5
说明:
	27017:27017 说明宿主机的端口和docker容器端口映射一致
image-20220321012037628
#3、进入mongo容器(要启动docker上的mongodb客户端就需要进入容器)
命令:
	docker exec -it deb0 bash
说明:
	deb0 是已经启动的容器的id
image-20220321012626034

3、开启远程访问

说明:我本地是装在window10上的

  1. 在安装mongodb的bin目录下输入指令:

    mongod --help
  2. 发现默认启动的mongodb支持本地访问

    image-20220322222718068
  3. 在任务管理器里面找到MongoDB

    image-20220322223301555
    #可执行文件路径:
    	D:\SOFT\JOB\MONGODB\bin\mongod.exe --config "D:\SOFT\JOB\MONGODB\bin\mongod.cfg" --service
  4. 、找到可执行文件路径所指定的配置文件:mongod.cfg

    #添加远程访问:
    	bindIP:0.0.0.0
    #在服务中重新启动即可	
    image-20220322223940344
  5. 如果是docker安装,默认是开启了远程访问的(启动的时候宿主机和启动的mongodb容器做了端口映射),如果在阿里云上安装需要开放端口27017

  6. 如果安装在Linux或Ubuntu上,需要关闭mongodb服务后,输入下面指定启动即可:

    ./mongod --port=27017 --dbpath=../data --logpath=../logs/mongo.log --bind_ip=0.0.0.0

四、核心概念(库、集合、文档)

    1. MongoDB中的库就类似传统关系数据库中库的概念,用来通过不同库隔离不同的数据;
    2. MongoDB中可以建立多个数据库,每一个库都有自己的集合和权限,不同的库也存放在不同的文件中;
    3. MongDB默认的数据库为“test”,数据库存储在启动指定的data目录中;
  • 集合

    1. 集合就是MongoDB文档组,类似于RDBMS(关系数据库管理系统:Relational Database Management System)中表的概念;
    2. 集合存在于数据库中,一个库可以创建多个集合;
    3. 每个集合没有固定的结构,这就意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性;
  • 文档

    1. 文档是集合中的一条记录,是一组键值对(即Bson);

    2. MongoDB的文档不需要设置相同的字段,并且相同字段不需要相同的数据类型,这与关系数据库有很大的区别,也是MongoDB的突出特点;

    3. 文档嵌套例子:

      {
          name:"lemo",
          age:"12",
          address:
          {
              city:"suzhou",
              country:"china",
              code:215000
          } ,
          scores:
          [
              {"name":"english","grade":3.0},
              {"name":"chinese","grade":2.0}
          ]
      }
  • 关系总结

    RDBMS MongoDB
    数据库 数据库
    集合
    文档
    字段

五、基本操作

1、库

  • 查看所有库

    #命令:
    	show databases | show dbs	
    #说明:
    	admin:从权限的角度来看,这是root数据库;要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限;一些特定的服务器段命令也只能从这个数据库运行,比如列出所有的数据库或关闭服务器、分片相关、做集群。
    	config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
    	local:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
    image-20220321030944099
  • 创建数据库

    #命令:
    	use 数据库名	
    image-20220321024403399
  • 删除数据库

    #命令:
    	db.dropDatabase()
    #说明:
    	db 表示当前客户端窗口下所在的数据库
    image-20220321030944099
  • 查看当前所在库

    #命令:
    	db	

2、集合

  • 查看库中所有集合

    #命令:
    	show collectons | show tables	
    image-20220321190329885
  • 创建集合

    #命令:
    	db.creatCollection('集合名称',[options])
    image-20220321191909027

    options可以是如下参数:

    字段 类型 描述
    capped 布尔 (可选)如果为true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。该值为true时,必须指定size参数
    size 数值 (可选)为固定集合指定一个最大值,即字节数。如果capped为teue,也需要指定该字段
    max 数值 (可选)指定固定集合中包含文档的最大数量。

    注意:当集合不存在的时,向文档中插入文档也会自动创建该集合

    image-20220321192849662
  • 删除集合

    #命令:
    	db.集合名称.drop()
    image-20220321193107763

3、文档

参考文档

https://docs.mongodb.com/manual/reference/method/
  • 插入文档

    1. 插入单条

      #命令:
      	db.集合名称.insert({"name":"lujiahong","age":24,"birth":2022-03-24})
      #说明:
      	mongodb是以bson格式存储文档,和json不同键可以加引号,也可以不加引号
    2. 插入多条

      #命令:
      #说明:
      	db.集合名称.insertMany(
      		[<document1>,<document2>,...],
      		{
      			writeConcern: 1,//写入策略,默认为1,即要求确认写操作,0是不要求
      			ordered: true	//指定是否按照顺序写入,默认为true,按顺序写入
      		}
      	)
      #写法:
      	db.集合名称.insert([
      		{"name":"lujiahong","age":24,"birth":2022-03-24},
      		{"name":"liuou","age":20,"birth":2022-03-25}
      	])
    3. 脚本方式

      //注意:在mongodb中每个文档都会有一个_id作为唯一标识,_id默认会自动生成如果手动指定将使用手动指定的值作为_id的值
      for(let i=0;i<20;i++){
          db.users.insert({"_id":i,"name":"lujiahong_"+i,"age":24})
      }
  • 查询所有

    #命令:
    	db.集合名称.find()
  • 删除文档

    #命令:
    	db.集合名称.remove(
    		<query>,
    		{
    			justOne: <boolean>,
    			writeConcern: <document>
    		}
    	)
    #说明:
    	query:(可选)删除文档的条件
    	justOne:(可选)如果设置为true或1,则只删除一个文档,如果不设置该参数,或使用默认值false,则删除所有匹配条件的文档
    	writeConcern:(可选)抛出异常的级别
  • 更新文档

    #命令:
    	db.集合名称.update(
    		<query>,
    		<update>,
    		{
    			upsert: <boolean>,
    			multi: <boolean>,
    			writeConcern: <document>
    		}
    	)
    #说明:
    	query:update的查询条件
    	update:update的对象和一些更新的操作符(如$,$inc..等),也可以理解为sql中update查询内set后面的
    	upsert:(可选)这个参数是update和insert的缩写,意思是如果不存在update的记录,是否插入objNew,true为插入,默认为false不插入
    	multi:(可选)mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查询出来多条记录全部更新
    	writeConcern:(可选)抛出异常的级别
    #操作:
    	#方式一(这个更新是将符合条件的全部更新成后面的文档,相当于先删除再更新):
    		db.集合名称.update({name:'zhangsan'},{name:'lisi',bir:new date()})
    	#方式二(保留原来数据更新,但是只更新符合条件的第一条数据):
    		db.集合名称.update({name:'zhangsan'},{$set:{name:'lisi'}})
    	#方式三(保留原来数据更新,更新符合条件的所有数据):
    		db.集合名称.update({name:'zhangsan'},{$set:{name:'lisi'}},{multi:true})
    	#方式四(保留原来数据更新,更新符合条件的所有数据,没有条件符合时插入数据):
    		db.集合名称.update({name:'zhangsan'},{$set:{name:'lisi'}},{multi:true,upsert:true})
    #注意:
    	写$set更新和不写$set更新文档的区别:前者是在匹配到的文档上进行更改,不会删除之前文档上已经存在的字段数据;而后者是先把匹配到的文档删除后,再更新上去,之前文档的字段就不复存在了,全是更新的文档字段数据;

六、文档查询

MongoDB查询文档使用find()方法。find()以非结构化的方式来显示所有文档

  • 语法

    #命令:
    	db.集合名称.find(query,projection)
    #说明:
    	query:(可选)使用查询操作符指定查询条件
    	projection:(可选)使用投影操作符指定返回的键(类似于sql中的返回指定字段还是返回*)。查询时返回文档中所有键值,只需省略该参数即可(默认省略)
    #注意:如果你需要以易读的方式来读取数据,可以使用pretty()方法,它是以格式化的形式来显示所有文档,类似于navicat中的美化sql
    	db.集合名称.find().pretty()
  • 对比语法

    MongoDB条件查询语句对比sql

    操作 格式 范例 RDBMS
    等于 {} db.col.find({name:’lujiahong’}).pretty() where name = ‘lujiahong’
    小于 {:{$it:}} db.col.find({age:{$it:50}}).pretty() where age < 50
    小于或等于 {:{$ite:}} db.col.find({age:{$ite:50}}).pretty() where age <= 50
    大于 {:{$gt:}} db.col.find({age:{$gt:50}}).pretty() where age > 50
    大于或等于 {:{$gte:}} db.col.find({age:{$gte:50}}).pretty() where age >= 50
    不等于 {:{$ne:}} db.col.find({age:{$ne:50}}).pretty() where age != 50
  • AND

    #命令:
    	db.集合名称.find({key1:value1},{key2:value2})
    #说明:类似于下面sql
    	where key1 = value1 AND key2 = value2
  • OR

    #命令:
    	db.集合名称.find({$or:[{key1:value1},{key2:value2}]}).pretty()
    #说明:类似于下面sql
    	where key1 = value1 OR key2 = value2
  • AND和OR联合

    #命令:
    	db.集合名称.find({{age:{$gt:50}},$or:[{key1:value1},{key2:value2}]}).pretty()
    #说明:类似于下面sql
    	where age > 50 AND (key1 = value1 OR key2 = value2) 
  • 数组中查询

    --测试数据
    	db.集合名称.insert({name:'lujiahong',age:24,likes:['吃饭','学习','看电影']})
    --执行数组查询(和字段查询一样)	
    	db.集合名称.find({likes:'吃饭'})
    --$size按数组长度进行查询
    	db.集合名称.find({likes:{$size:3}})
  • 模糊查询

    #命令:
    	db.集合名称.find({like:/吃/})
    #说明:类似于下面sql
    	where likes like '%吃%'	
    #注意:
    	在mongodb中使用正则表达式可以实现近似模糊查询功能
  • 排序

    #命令:
    	db.集合名称.find().sort({name:1,age:-1})
    #说明:类似于下面sql,其中1表示升序,-1表示降序
    	order by name,age
  • 分页

    #命令:
    	db.集合名称.find().sort({条件}).skip(start).limit(rows)
    #说明:类似于下面sql
    	limit start,rows
  • 总条数

    #命令:
    	db.集合名称.count() | db.集合名称.find({条件}).count()
    #说明:类似于下面sql
    	select count(0) from ...
  • 去重

    #命令:
    	db.集合名称.distinct('字段') 
    #说明:类似于下面sql
    	select distinct name from ...
  • 指定返回值

    #命令:
    	db.集合名称.find({条件},{name:1,age:1}).pretty()
    #说明:类似于下面sql,上面name和age字段为1表示返回,若为0表示不返回,但是0和1不能同时指定
    	select name ,age from table where 条件

七、$type

1、说明

$type操作符是基于bson类型来检索集合中匹配的数据类型,并返回i结果

MongoDB中可以使用的类型如下表所示:

类型 数字 备注
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已废弃
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
Javascript(with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1
Max key 127

注意:mongodb把对应的类型映射成了对应的数字,在根据类型查询时,指定对应类型的数字即可实现查询,也可通过原生类型

2、使用

  1. 先来插入一些测试数据

    for(let i = 0;i < 10;i++){
        db.col.insert({
        	name: 'lujiahong_'+i,
        	age: 20+i,
        	birth: '1998-11-'+(1+i),
    	    likes:['吃饭'+i,'学习'+i,'看电影'+i],
    	    job:{name:'java开发工程师'+i,salary:10000+i*100},
    	    home:[{name:'lusaoqiang'+i,relative:"father"+i},{name:'liuou'+i,relative:"wife"+i}],
    	    des:[{eat:'fruit'+i,plays:['basketball'+i,'football'+i],blog:'https://ljh130168.github.io'+i}]
    	})
    }
  2. 获取col集合中name为String的数据

    db.col.find({name:{$type:2}}).pretty() | da.col.find({name:{$type:string}}).pretty()
  3. 获取col集合中likes为Array的数据

    db.col.find({name:{$type:4}}).pretty() | da.col.find({name:{$type:array}}).pretty()

八、索引

  • 说明

    1. 索引通常能极大的提高查询效率,如果没有索引,MongoDB在读取数据的时候必须扫描集合中的每一个文件并选取那些符合条件查询的记录。
    2. 这种扫描全集合的查询效率非常低的,特别在处理大量数据时,查询可以花费几十秒甚至几分钟,这对网站的性能是非常致命的。
    3. 索引是特殊的数据结构,索引存储在一个易于读取的数据集合中,索引是对数据库中一列或多列进行排序的一种结构。
  • 原理

    1. 从根本上说,MongoDB中的索引与其它数据库系统中的索引类型。

    2. MongoDB在集合层面上定义了索引,并支持对MongoDB集合中的任何字段或文档子字段进行索引。

      image-20220322022456071
  • 操作

    1. 创建索引

      #命令:
      	db.集合名称.createIndex(keys,option) 
      #举例:
      	db.集合名称.ctrateIndex({title:1,des:-1})
      #说明:
      	语法中的key值是你要创建索引的字段,1表示该字段按升序创建索引,-1表示该字段按降序创建索引
    2. createIndex()接受可选参数列表(即option)如下:

      Paramter Type Description
      background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加”background“可选参数。”background“默认值为false
      unique Boolean 建立索引是否唯一。指定为true时创建唯一索引。默认值为false
      name String 索引的名称。如果未指定,MongoDB通过连接索引的字段名和排序顺序生成一个索引名称
      sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档。默认值为false
      expireAfterSeconds integer 指定一个以秒为单位的数值,完成TTL设定,设定集合的生存时间
      v index version 索引版本号。默认的索引版本取决于mongodb创建索引时运行的版本
      weights document 索引权重值,数值在1到99999之间,表示该索引相对于其它索引字段的得分权重
      default_language String 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。默认为英语
      language_override String 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为language
    3. 查看集合索引

      #命令:
      	db.集合名称.getIndexes()
    4. 查看集合索引大小

      #命令:
      	db.集合名称.totalIndexSize()	
    5. 删除集合所有索引

      #命令:
      	db.集合名称.dropIndexes()
    6. 删除集合指定索引

      #命令:
      	db.集合名称.dropIndex("索引名称")
  • 复合索引

    复合索引即RDBMS中的组合索引,把多个列一起创建的索引,同样满足最左前缀原则(不然索引查询失效)

    形如下面的语句就是创建对于库下某集合的复合索引

    #命令:
    	db.集合名称.createIndex({name:1,des:-1},{name:name_des_index})
    #说明:
    	上面语句就是创建了某个集合以字段name升序、以字段des降序的复合索引,该复合索引名称为:name_des_index

九、聚合

1、说明

  1. MongoDB中聚合主要用于处理数据(统计平均值,求和…),并返回计算后的数据结果;
  2. 有点类似与sql中的conunt(*);

2、使用

  1. 插入测试数据

    db.myCol.insert([
    	{
    		title:'MongoDB Overview',
    		des:'MongoDB is no sql database',
    		author:'runoob.com',
    		url:'http://www.runoob.com',
    		tags:['mongodb','database','NoSQL'],
    		likes:100
    	},
    	{
    		title:'NoSQL Overview',
    		des:'NOSQL database is very fast',
    		author:'runoob.com',
    		url:'http://www.runoob.com',
    		tags:['mongodb','database','NoSQL'],
    		likes:10
    	},
    	{
    		title:'Neo4j Overview',
    		des:'Neo4j is no sql database',
    		author:'neo4j.com',
    		url:'http://www.neo4j.com',
    		tags:['neo4j','database','NoSQL'],
    		likes:180
    	},
    ])
  2. 计算每个作者所写的文章数

    #命令:
    	db.myCol.aggregate([
    		{
    			$group:{_id:"$author",num_tutorial:{$sum:1}}
    		}
    	])
    #说明:
    	_id不是文档的_id,而是告诉语句是以字段author分组的标识,字段前需加上$符号;
    	num_tutorial表示用该字段来记录文章数;
    	$sum是聚合表达式,表示对分组后的数据进行求和,后面的值1表示对求和的数要象剩的值,如果值是2就表示对求和的值剩以2;
    image-20220322191608222
  3. 常见的聚合表达式

    表达式 描述 实例
    $sum 计算总和 db.myCol.aggregate([{$group:{_id:”$author”,num_tutorial:{$sum:”$likes”}}}])
    $avg 计算平均值 db.myCol.aggregate([{$group:{_id:”$author”,num_tutorial:{$avg:”$likes”}}}])
    $min 获取集合中所有文档对应值得最小值 db.myCol.aggregate([{$group:{_id:”$author”,num_tutorial:{$min:”$likes”}}}])
    $max 获取集合中所有文档对应文档最大值 db.myCol.aggregate([{$group:{_id:”$author”,num_tutorial:{$max:”$likes”}}}])
    $push 将值加入一个数组中,不会判断是否有重复的值 db.myCol.aggregate([{$group:{_id:”$author”,url:{$push:”$url”}}}])
    $addToSet 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在,则不加入 db.myCol.aggregate([{$group:{_id:”$author”,url:{$addToSet:”$url”}}}])
    $first 根据资源文档的排序获取第一个文档的数据 db.myCol.aggregate([{$group:{_id:”$author”,first_url:{$first:”$url”}}}])
    $last 根据资源文档的排序获取最后一个文档的数据 db.myCol.aggregate([{$group:{_id:”$author”,last_url:{$last:”$url”}}}])

十、整合应用

说明:这里主要以springboot应用为基础应用进行整合开发

image-20220322225205578

1、环境搭建

  1. 引入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
  2. 编写配置

    #无密码这样写:
        #mongodb(协议)://127.0.0.1(主机):27017(端口)/lujiahong(库名)
        spring.data.mongodb.uri=mongodb://127.0.0.1:27017/lujiahong
    #有密码这样写:
        spring.data.mongodb.host=127.0.0.1
        spring.data.mongodb.port=27017
        spring.data.mongodb.database=lujiahong
        spring.data.mongodb.username=root
        spring.data.mongodb.password=root

2、集合操作

  1. 创建集合

    //1、创建集合
    @Test
    public void testCreateCollection(){
        //创建集合的时候判断此集合是否存在,不存在再创建 ,创建重复的集合会报错
        if (!this.mongoTemplate.collectionExists("user")) {
            this.mongoTemplate.createCollection("user");
        }
    }
  2. 删除集合

    //2、删除集合
    @Test
    public void testDropCollection(){
        //删除集合操作可重复删除同一个集合,不会报错
        this.mongoTemplate.dropCollection("user");
    }
  3. 相关注解(实体类)

    • @Document
      1. 修饰范围:用在类上
      2. 作用:用来映射这个类的一个对象为mongo中的一条文档
      3. 属性:(value、collection)用来指定操作的集合名称
    • @Id
      1. 修饰范围:用在成员变量、方法上
      2. 作用:用来将成员变量的值映射为文档的_id值
    • @Field
      1. 修饰范围:用在成员变量、方法上
      2. 作用:用来将成员变量以及值映射为文档中的一个key、value
      3. 属性:(name、value)用来指定在文档中的key的名称,默认为成员变量名
    • @Transient
      1. 修饰范围:用在成员变量、方法上
      2. 作用:用来指定该成员变量,不参与文档的序列化,即不再文档中显示该字段

3、文档操作

  1. 查询

    Criteria(查询条件) MongoDB 说明
    Criteria and (String key) $and 并且
    Criteria andOperator(Criteria… criteria) $and 并且
    Criteria orOperator(Criteria… criteria) $or 或者
    Criteria gt (Object o) $gt 大于
    Criteria gte (Object o) $gte 大于等于
    Criteria in (Object… o) $in 包含
    Criteria is (Object o) $is 等于
    Criteria lt(Object o) $lt 小于
    Criteria lte (Object o) $lte 小于等于
    Criteria nin (Object… o) $nin 不包含
  2. 添加

    @Test
    public void testSaveOrInsertDocument(){
        //save和insert都可以作为文档的添加操作,但两者之间有区别:
        //1、插入重复数据时:save可以对已存在的数据进行更新,而insert会报DuplicateKeyException提示主键重复
        //2、批处理插入时:insert可以一次性插入整个数据,效率高,而save会遍历整个数据,逐条插入或更新,效率低
        this.mongoTemplate.save(new User(1,"lujiahong",23,new Date(),1400.5));
        this.mongoTemplate.insert(new User(2,"lujiahong2",23,new Date(),1400.56));
        //insert批量插入支持集合,save不行
        //insert提供三种方式指定要插入到的集合名称
        this.mongoTemplate.insert(Arrays.asList(new User(3,"lujiahong2",23,new Date(),1400.56),
                new User(4,"lujiahong2",23,new Date(),1400.56)),User.class);
        this.mongoTemplate.insert(Arrays.asList(new User(5,"lujiahong2",23,new Date(),1400.56),
                new User(6,"lujiahong2",23,new Date(),1400.56)),"users");//users为User实体类对应的集合名称
        this.mongoTemplate.insertAll(Arrays.asList(new User(7,"lujiahong2",23,new Date(),1400.56),
                new User(8,"lujiahong2",23,new Date(),1400.56)));
    }
  3. 查询

    @Test
       public void testFindDocument(){
           List<User> users;
           /**
            * 1、查询所有
            */
           //方式一:
           users = this.mongoTemplate.findAll(User.class);
           //方式二:
           users = this.mongoTemplate.findAll(User.class,"users");
           //方式三:
           users = this.mongoTemplate.find(new Query(),User.class);//new Query()代表空查询条件,即查询全部
       
           /**
            * 2、查询单个byId
            */
           User user = this.mongoTemplate.findById(1, User.class);
       
           /**
            * 3、条件查询
            */
           // is 等于
           users = this.mongoTemplate.find(Query.query(Criteria.where("name").is("lujiahong")),User.class);
           // gt 大于
           users = this.mongoTemplate.find(Query.query(Criteria.where("age").gt(23)),User.class);
           // gte 大于等于
           users = this.mongoTemplate.find(Query.query(Criteria.where("age").gte(23)),User.class);
           // lt 小于
           users = this.mongoTemplate.find(Query.query(Criteria.where("age").lt(23)),User.class);
           // lte 小于等于
           users = this.mongoTemplate.find(Query.query(Criteria.where("age").lte(23)),User.class);
           // in 包含
           users = this.mongoTemplate.find(Query.query(Criteria.where("name").in("lu")),User.class);
           // nin 包含
           users = this.mongoTemplate.find(Query.query(Criteria.where("name").nin("lu")),User.class);
           // and 并且
           users = this.mongoTemplate.find(Query.query(Criteria.where("name").is("lujiahong").and("age").is(23)),User.class);
           // andOperator 并且
           users = this.mongoTemplate.find(Query.query(Criteria.where("name").is("lujiahong").andOperator(Criteria.where("age").is(23))),User.class);
           // or 或者
           Criteria criteria = new Criteria();
           criteria.orOperator(Criteria.where("name").is("lujiahong"),Criteria.where("age").is(23));
           users = this.mongoTemplate.find(Query.query(criteria),User.class);
           // and or 并且或者
           users = this.mongoTemplate.find(Query.query(Criteria.where("name").is("lujiahong").orOperator(Criteria.where("age").is(23))),User.class);
           // sort 排序
           users = this.mongoTemplate.find(new Query().with(Sort.by(Sort.Order.desc("age"))),User.class);
           // skip limit 分页
           users = this.mongoTemplate.find(new Query().skip(0).limit(4),User.class);
           // findDistinct 去重(最后一个参数,即要去重字段的对应类型)
           List<Integer> distinct = this.mongoTemplate.findDistinct(new Query(), "age", User.class, Integer.class);
           distinct.forEach(System.out::println);
           // skip limit 总条数
           long count = this.mongoTemplate.count(new Query(), User.class);
       
           /**
            * 按bson格式查询,BasicQuery是Query的子类
            */
           Query basicQuery = new BasicQuery("{name:'lujiahong'}");
           users = this.mongoTemplate.find(basicQuery,User.class);
           users.forEach(System.out::println);
       }
  4. 更新

    @Test
    public void testUpdateDocument(){
        //更新条件
        Query query = new Query(Criteria.where("age").is(23));
        //更新内容
        Update update = Update.update("name", "nihao");
       
        UpdateResult updateResult;
        //单条更新
        updateResult = this.mongoTemplate.updateFirst(query, update, User.class);
        //多条更新
        updateResult = this.mongoTemplate.updateMulti(query,update,User.class);
        //更新插入
        updateResult = this.mongoTemplate.upsert(query,update,User.class);
       
        //匹配条数
        long matchedCount = updateResult.getMatchedCount();
        //修改条数
        long modifiedCount = updateResult.getModifiedCount();
        //插入id
        BsonValue upsertedId = updateResult.getUpsertedId();
    }
  5. 删除

    @Test
    public void testRemoveDocument(){
        //删除所有
        this.mongoTemplate.remove(new Query(),User.class);
        //条件删除
        this.mongoTemplate.remove(Query.query(Criteria.where("name").is("lujahong")),User.class);
    }

十一、副本集群


十二、分片集群


文章作者: LJH
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LJH !
  目录