MongoDB ⛹️♀️ @CreateByShadow
一、是什么?
面向文档的NoSQL数据库,用于大量数据存储
专用名词:
1、数据库 - show dbs(databases) 包含多个集合
1、集合 collection 包含多个文档
2、文档 :集合中的记录,文档包含多个字段名称和值
3、字段:JSON的名称
4、游标:执行查询结果集的指针
5、JSON 文档中存储的数据格式
####二、为什么用?
1、非常灵活,可以适应实际的业务环境和需求
2、支持多种查询
3、支持索引,提高搜索性能
4、副本集、高可用
5、负载均衡、分片
二、与 RDBMS的对照
RDBMS | MongoDB | |
---|---|---|
Table | Collection | RDBMS - 表;MongoDB - 集合 |
Row | Document | RDBMS - 数据行;MongoDB - 文档 |
Column | Field | RDBMS - 数据列;MongoDB - 字段 |
JOIN | Embedded Document | RDBMS - 关联查询;MongoDB - 内嵌文档 |
三、数据库类型
类型 | 实现 |
---|---|
关系型数据库 | MySQL、Oracle、SQL Server |
基于键值对 | Redis、DynamoDB、Memcached |
大数据存储(聚合查询高性能) | Cassandra、Hbase、Hypertable |
基于Hadoop生态 | Hive、Spark |
面向文档(JSON/XML) | MongoDB、CouchDB、Amazon SimpleDB |
基于图形(社交网络、物流、空间数据) | Neo4J、Infinite Graph、OrientDB、FlockDB |
快速检索 | lucence、Solr、Elasticsearch |
四、3V + 3高
- 3V
- 海量(Volume)
- 多样(Variety)
- 实时(Velocity)
- 3高
- 高并发
- 高可扩
- 高性能
五、ACID、CAP 、BASE
ACID:
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
CAP:
强一致性(Consistency)
可用性(Availability)
分区容错性(Partition tolerance)
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍的系统,通常性能不是特别高。(ZK集群)
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。(Redis集群)BASE:
基本可用(Basically Available)
软状态(Soft state)
最终一致性(Eventually consistent)
六、安装及连接
-
解压安装包
tar -zxvf mongodb-linux-x86_64-rhel62-4.0.23.tgz
-
创建mongodb数据文件夹
mkdir data mkdir logs mkdir conf
-
创建文件
cd ./logs touch mongdb.log cd ../conf/ touch mongodb.conf
-
编写配置文件
vim mongodb.conf
输入一下内容
#数据库路径 dbpath=/xx/xxx/mongodb/mongo/data #日志输出文件路径 logpath=/xx/xxx/mongodb/mongo/logs/mongodb.log #错误日志采用追加模式 logappend=true #启用日志文件,默认启用 journal=true #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false quiet=true #端口号 默认为27017 port=27017 #允许远程访问 bind_ip=0.0.0.0 #开启子进程 fork=true #开启认证,必选先添加用户 auth=true
-
配置环境变量
vim /etc/profile
添加内容
export PATH=$PATH:/xx/xxx/mongodb/mogon/bin
-
生效配置文件
source /etc/profile
-
启动 mongo服务
./mongod -f /xx/xxx/mongodb/mongo/conf/mongodb.conf 或者 ./mongod --config /xx/xxx/mongodb/mongo/conf/mongodb.conf
-
查看服务是否正常启动
netstat -lanp | grep 27017 或者 ps -ef | grep mongo
-
连接mongo服务
./mongo ./mongo --host=127.0.0.1 --port=27017
-
添加用户认证
>use admin >db.createUser({ user:"root",pwd:"123456",roles[{ role:"root",db:"admin"}]}) >db.shutdowServer()
-
认证
>use admin >db.auth('root','123456') >show dbs
-
工具连接
- MongoDBCompass
- Robo 3T
- Studio 3T
- NoSQLbooster
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OQi0sNRs-1624682480475)(./auth.jpg)]
七、基础操作
1、数据库操作
-
创建(不存在会自动创建并切换到该库,存在则切换到该库)
use 数据库名
>use shadow
-
查看
>db >show dbs >show databases
-
删除(use 到当前库然后执行)
>db.dropDatabase()
-
修复
./mongod --repair --dbpath=./data
2、集合操作
-
创建
-
显式
db.createCollection(集合名称)
>db.createCollection("shop")
-
隐式(没有shop集合会自动创建)
>db.shop.insert({ x:1})
-
-
删除 (db.集合名称.drop())
>db.shop.drop()
-
查看
>show collections
3、文档操作
-
新增
db.集合名称.insert()
db.集合名称.insertOne()
db.集合名称.save() #通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入
db.集合名称.insertMany([])
>db.shop.insert({ name:"华为",price:6666}) >db.shop.insertOne({ name:"伏地魔"}) >db.shop.save({ name:"马士兵教育"}) >db.shop.insertMany([{ name:"华为",price:1111},{ name:"小米",price:2222}])
-
查询
db.集合名称.find(query,[projection])
query :可选,查询筛选器 JSON 对象
projection:可选,结果字段 JSON 对象
>db.shop.find().pretty() #查询全部 >db.shop.find({ name:"华为"}) #带条件查询 >var c = db.shop.find() #得到游标 >while(c.hasNext()){ print(tojson(c.next()));} #游标迭代 >db.shop.find().limit(2).forEach(printjson) #limit()个数限制,forEach()迭代 >db.shop.find().sort({ age:-1}) #sort()排序 按照age字段排序 -1表示降序,1表示升序
-
删除
db.集合名称.remove({})
>db.shop.remove({ }) # 删除所有 >db.shop.remove({ name:"伏地魔"}) # name是伏地魔的 >db.shop.remove({ price:{ $lte:2000}}) # price小于等于2000的
-
更新
db.集合名称.update(query,update)
db.集合名称.updateOne(query,update)
db.集合名称.updateMany(query,update)
query:条件,JSON对象
update: 更新字段 JSON对象
>db.shop.update({ name:"小米"},{ $set:{ price:3333}}) >db.shop.updateOne({ y:111},{ $set:{ price:3333}}) >db.shop.updateMany({ price:3333},{ $set:{ age:18}})
-
聚合
相当于 SQL 查询的 GROUP BY,LEFT JOIN等操作
db.集合名称.count()
db.集合名称.distinct(Field) – Field字段名称必须
>db.shop.count() #统计文档数量 >db.shop.distinct("price") #字段去重并返回去重后的值(数组)
4、常用的操作符
关系 | 格式 | 例子 |
---|---|---|
等于 | {< key > : < value >} | db.shop.find({name:“小米”}).pretty() |
小于 | {< key > : {$lt : < value >}} | db.shop.find({price:{$lt:100}}).pretty() |
小于等于 | {< key > : {$lte : < value >}} | db.shop.find({price:{$lte:100}}).pretty() |
大于 | {< key > : {$gt : < value >}} | db.shop.find({price:{$gt:100}}).pretty() |
大于等于 | {< key > : {$gte : < value >}} | db.shop.find({price:{$gte:100}}).pretty() |
不等于 | {< key > : {$ne : < value >}} | db.shop.find({price:{$ne:100}}).pretty() |
and | {key1:value1,key2:value2} {$and:[{key1:value1},{key2:value2}]} |
db.shop.find({name:“小米”,price:100}).pretty() db.shop.find({$and:[{name:“小米”},{price:100}]}).pretty() |
or | {$or:[{key1:value1},{key2:value2}]} | db.shop.find({$or:[{name:“小米”},{price:100}]}).pretty() |
and or 联合 | {key1:{ KaTeX parse error: Expected 'EOF', got '}' at position 13: lte : value1}̲,or:[{key2 : value2},{key3 : value3}]} | db.shop.find({price:{ KaTeX parse error: Expected 'EOF', got '}' at position 8: lte:100}̲,or:[{name:“小米”},{name:“z”}]}).pretty() |
$type | {key1 : {$type :‘string’}} | db.shop.find({addr:{$type:‘string’}}).pretty() |
$set 更新或添加字段 | {$set : {key : value}} | db.shop.update({name:“zzz”},{$set:{email:111}}) |
$unset 删除字段 | {$unset : {key : 1}} | db.shop.update({name:“zzz”},{$unset:{email:1}}) |
$inc 数字增减 | {$inc : {key:value}} | db.shop.update({name:“zzz”},{$inc:{price:10}}) |
$pull 数组删除元素 | {$pull : {key : value }} | db.shop.update({name:“zzz”},{$pull:{addr:“xx”}}) |
$pop 删除数组firts/last | {$pop : {key : -1/1}} | db.shop.update({name:“zzz”},{$pop:{addr:-1}}) |
$rename 修改字段名称 | {$rename : {oldName : newName}} | db.shop.update({name:“zzz”},{$rename:{addr : address}}) |
$bit 位操作 integer类型 | {$bit : {and/or : 5}} | db.shop.insert({name:“qqq”,bits: NumberInt(2)}) db.shop.update({name:“qqq”},{$bit : {bits: {or: NumberInt(1)}}}) |
5、常用的方法
用途 | 方法 | 例子 |
---|---|---|
分页查询 | limit(n) | db.shop.find().limit(2).pretty() |
跳越查询 | skip(n) | db.shop.find().skip(2).pretty() |
排序(1:升序 -1:降序) | sort({key1:1/-1}) | db.shop.find({},{name:1,_id:0,price:1}).sort({price:-1}).pretty() |
统计 | count() | db.shop.count() |
去重 | distinct(key) | db.shop.distinct(“name”) |
6、聚合操作
表达式 | 功能 | 例子 |
---|---|---|
$sum | 求和 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",num_price:{ s u m : " sum:" sum:"price"}}}]) |
$avg | 求平均值 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",num_price:{ a v g : " avg:" avg:"price"}}}]) |
$min | 最小值 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",num_price:{ m i n : " min:" min:"price"}}}]) |
$max | 最大值 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",num_price:{ m a x : " max:" max:"price"}}}]) |
$push | 结果文档中插入值到一个数组中 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",price:{ p u s h : " push:" push:"price"}}}]) |
$addToSet | 结果文档中插入值到一个数组中,但不创建副本 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",price:{ a d d T o S e t : " addToSet:" addToSet:"price"}}}]) |
$first | 获取第一个文档数据 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",price:{ f i r s t : " first:" first:"price"}}}]) |
$last | 获取最后一个文档数据 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name",price:{ l a s t : " last:" last:"price"}}}]) |
7、管道操作
表达式 | 功能 | 例子 |
---|---|---|
$project | 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档 | db.shop.aggregate({$project : {name: 1,price:1,_id:0}}) |
$match | 用于过滤数据,只输出符合条件的文档 | db.shop.aggregate([{$match:{name:“zzz”}}]) |
$limit | 用来限制MongoDB聚合管道返回的文档数 | db.shop.aggregate({$limit: 2}) |
$skip | 跳过指定数量的文档,并返回余下的文档 | db.shop.aggregate({$skip: 5}) |
$unwind | 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值 addrs是数组 | db.shop.aggregate([{ u n w i n d : " unwind:" unwind:"addrs"}]) |
$group | 将集合中的文档分组,可用于统计结果 | db.shop.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"name"}}]) |
$sort | 将输入文档排序后输出 | db.shop.aggregate([{$sort:{price:-1}}]) |
$geoNear | 输出接近某一地理位置的有序文档 | ## |
8、备份与恢复
-
备份
# 导出当前机器上的 test 库到当前位置 ./mongodump -h localhost:27017 -uroot -p123456 --authenticationDatabase=admin -d test -o .
-
-h:
MongoDB 所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-
-d:
需要备份的数据库实例,例如:test
-
-o:
备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
-
-
恢复
#导入/shadow目录下的库 ./mongorestore -h localhost:27017 -d shadow -dir ./shadow/
-
–host <:port>, -h <:port>:
MongoDB所在服务器地址,默认为: localhost:27017
-
–db , -d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
-
–drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
-
< path >:
mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。
你不能同时指定
和 --dir 选项,–dir也可以设置备份目录。 -
–dir:
指定备份的目录
你不能同时指定 < path > 和 --dir 选项。
-
9、监控
-
mongostat
./bin/mongostat -h localhost -p 27017 -uroot -p123456 --authenticationDatabase=admin
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHy2BjHx-1624682480478)(./mongostat.jpg)]
-
mongotop
./bin/mongotop -h localhost -p 27017 -uroot -p123456 --authenticationDatabase=admin 10
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sXsdLcdt-1624682480480)(./mongotop.jpg)]
八、Java-MongoDB - 单机
1、pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>4.0.4&