MongoDB的应用场景
mondoDB是一个分布式的文件存储数据库, 同时他也是一个NoSql数据库, 主要是为WEB应用提供可扩展的高性能解决方案, MongoDB是一个内存型数据库, 因此会存在数据丢失的问题, 所以应用时不能将严格的保证不丢失的数据放到MongoDB中, 最为最终的存储解决方法;
  • 网站实时数据: 日志, 用户行为, 时间轴
  • 数据缓存: 缓存的数据是临时的, 要在关系型数据库中保存
  • 大尺寸低价值数据: 图片文件或者视频文件
  • 高伸缩性场景: 机器任意增加或减少的场景
  • 对象或者JSON存储
不适用范围
  • 高度事务性系统: 金融系统
  • 高机密的用户数据
  • 结构化关联查询要求非常高的: 如报表系统
MongoDB术语
mysql mongoDB 解释
DataBase DataBase 数据库
table collection 表或集合
Row Dcoument 数据行
Colum Field 数据列,字段
index index 索引
Table join 不支持 表关联
PremaryKey ObjectID 主键
数据类型
数据类型 说明 举例
Null null值 {x: null}
Boolean 布尔值 {x: true}
Integer 整数 {x: 1}
Double 浮点数 {x: 3.14}
String 字符串 {x: "字符串"}
ObjectID 对象ID {x: ObjectID()}
Date 时间 {x: new Date()}
TimeStamp 时间戳 {x: 142343214123}
Array 数组 {x: ["a","b"]}
Object 内嵌文档 {x: {"a","b"}}
单机MongoDB的安装和启动
  1. 官网下载tar包并解压
  2. 创建data数据目录, 和logs日志目录
  3. 创建配置文件mono.conf, 内容如下:
  4. 配置环境变量: vi /etc/profile, 最后一行添加export PATH=$PATH:/mongodb/mongodb-linux-x86_64-debian92-4.0.3/bin, 然后执行source /etc/profile
  5. 使用./bin/mongod -f ./mongo.conf启动
  6. 执行./mongo看是否能进入程序
mongo.conf内容

dbpath=/mongodb/data
logpath=/mongodb/logs/mongo.log
logappend=true
journal=true
quiet=true
port=27017
fork=true #后台运行
bind_ip=0.0.0.0 #允许任何IP进行连接
auth=false #是否授权连接
连接使用工具

Robo3T

MongoDB架构
写数据过程

image.png

读数据过程

image.png
mongos是mongod的协调中心, 客户端和服务端交互的通道;
mongod Config是配置中心
mongod是数据库

spring-boot整合MongoDB
  • 添加依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
  • yml文件中添加相关配置
spring.data.mongodb.uri=mongodb://192.168.1.11:27017/testdb
  • 注入MongoTemplate使用即可
mongoDB语法
x    #查询年龄大于等于 25 小于等于 27 的人
db.t_member.find({age:{$gte:25,$lte:27}},{_id:0,name:1,age:1})
#查询出所有国籍不是韩国的人的数学成绩
db.t_member.find({country:{$ne:"韩国"}},{_id:0,name:1,country:1})

$in 或 $nin
#查询国籍是中国或美国的学生信息
db.t_member.find({country:{$in:["China","USA"]}},{_id:0,name:1:country:1})

#查询语文成绩大于 85 或者英语大于 90 的学生信息
db.t_member.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]},{_id:0,name:1,c:1,e:1})
#把中国国籍的学生上增加新的键 sex
db.t_member.update({country:"China"},{$set:{sex:"m"}},false,true)
#查询出 sex 为 null 的人
db.t_member.find({sex:{$in:[null]}},{_id:0,name:1,sex:1})

#查询出名字中存在”li”的学生的信息
db.t_member.find({name:/li/i},{_id:0,name:1})

$not 和$nin 的区别是$not 可以用在任何地方儿$nin 是用到集合上的
#查询出名字中不存在”li”的学生的信息
db.t_member.find({name:{$not:/li/i}},{_id:0,name:1})

#查询喜欢看 MONGOD 和 JS 的学生
db.t_member.find({books:{$all:["JS","MONGODB"]}},{_id:0,name:1})
#查询第二本书是 JAVA 的学习信息
db.t_member.find({"books.1":"JAVA"},{_id:0,name:1,books:1})

#查询出喜欢的书籍数量是 4 本的学生
db.t_member.find({books:{$size:4}},{_id:0,name:1})
查询出喜欢的书籍数量大于 4 本的学生本的学生
增加 size 键
db.t_member.update({},{$set:{size:4}},false,true)
添加书籍,同时更新 size
db.t_member.update({name:"jim"},{$push:{books:"ORACL"},$inc:{size:1}
})

查询大于 3 本的
db.t_member.find({size:{$gt:4}},{_id:0,name:1,size:1})

#查询出 Jim 书架中第 2~4 本书
db.t_member.find({name:"jim"},{_id:0,name:1,books:{$slice:[1,3]}})
#查询出最后一本书
db.t_member.find({name:"jim"},{_id:0,name:1,books:{$slice:-1}})

查询出在 K 上过学且成绩为 A 的学生
绝对查询,顺序和键个数要完全符合
db.t_member.find({school:{school:"K","score":"A"}},{_id:0,name:1})
对象方式,但是会出错,多个条件可能会去多个对象查询
db.t_member.find({"school.school":"K","school.score":"A"},{_id:0,name:1})

正确做法单条条件组查询$elemMatch
db.t_member.find({school:{$elemMatch:{school:"K",score:"A"}},{_id:0,name:1})
db.t_member.find({age:{$gt:22},books:"C++",school:"K"},{_id:0,name:1,age:1,books:1,school:1})

分页与排序
1)limit 返回指定条数 查询出 persons 文档中前 5 条数据:
db.t_member.find({},{_id:0,name:1}).limit(5)
2)指定数据跨度 查询出 persons 文档中第 3 条数据后的 5 条数据
db.t_member.find({},{_id:0,name:1}).limit(5).skip(3)
3)sort 排序 1 为正序,-1 为倒序
db.t_member.find({},{_id:0,name:1,age:1}).limit(5).skip(3).sort({age:1})

$inc :只使用于数字类型,可以为指定键值对的数字类型进行加减操作:
db.t_member.update({name:"zhangsan"},{$inc:{age:2}})

执行结果是名字叫“zhangsan”的年龄加了 2
$unset : 删除指定的键
db.t_member.update({name:"zhangsan"},{$unset:{age:1}})

$push : 数组键操作:1、如果存在指定的数组,则为其添加值;2、如果不存在指定的数组,则
创建数组键,并添加值;3、如果指定的键不为数组类型,则报错;
$addToSet : 当指定的数组中有这个值时,不插入,反之插入
#则不会添加到数组里
db.t_member.update({name:"zhangsan"},{$addToSet:{classes:"English"}});

$pop:删除指定数组的值,当 value=1 删除最后一个值,当 value=-1 删除第一个值
#删除了最后一个值
db.t_member.update({name:"zhangsan"},{$pop:{classes:1}})
$pull : 删除指定数组指定的值
#$pullAll 批量删除指定数组
db.persons.update({name:"zhangsan"},{$pull:{classes:"Chinese"}})
#若数组中有多个 Chinese,则全删除
db.t_member.update({name:"zhangsan"},{$pull:{classes:["Chinese"]}})
$ : 修改指定数组时,若数组有多个对象,但只想修改其中一些,则需要定位器:
db.t_member.update({"classes.type":"AA"},{$set:{"classes.$.sex":"male"}})
$addToSet 与 $each 结合完成批量数组更新操作
db.t_member.update({name:"zhangsan"},{$set:{classes:{$each:["chinese","art"]}}})
MongoDB高可用
cluster 主从架构(M-A-S, A代表仲裁节点, 该节点不承担数据存储功能, 这台机器挂点也没问题, 主从中其中一台可以承担这个角色)

创建用户命令:

db.createUser({user:"admin",pwd:"123",roles:[{role:"dbAdmin",db:"testdb"}]})
db.auth("admin","123")
使用show roles查看所有的角色
config文件配置

除了上面的配置之外, 再添加如下字段:

#表示集群的名字
replSet=... 

三台机器都是用相同的配置并启动;

随意登录一台机器进行集群初始化
#使用admin数据库
use admin
cfg={_id:"replSet02",members:[{_id:0,host:'ip1:27017',priority:9},{_id:1,host:'ip2:27017',priority:1},{_id:2,host:'ip3:27017',arbiterOnly:true}]};

#使配置生效
rs.initiate(cfg)
#查看状态
rs.status()
mongodb官方推荐模式(需要使用至少8台服务器)
  1. 配置文件中添加该配置shardsvr=true, 配置三台机器, 配置相同的集群名称, 启动, 然后使用上面的方法是配置生效;
  2. 配置文件中添加configsvr=true, 配置三台机器, 配置相同的集群名称, 注意不要和上面的相同, 启动, 和一种相同的操作;
  3. 配置路由节点添加如下配置:
configdb=configrs/ip1:28001,ip2:28001,ip3:20881

去掉dbpath和replSset配置, 启动:

./mongos -f /mongodb.cfg
  1. 连接路由节点进行配置:
mongo 192.168.209.128:30000
#这里必须连接路由节点
sh.addShard("shard001/192.168.209.128:27001");
sh.addShard("shard002/192.168.209.128:27017");
#shard001、shard002 表示 replica set 的名字 当把主节点添加到 shard 以后,会
自动找到 set 里的主,备,决策节点
use testdb
sh.enableSharding("testdb") #testdb is database name
sh.shardCollection("testdb.testcon",{"name":”hashed”})
db.collection.status()

整个架构和es架构的思想比较类似, 只有数据量真的较大时使用才会显示他的作用;

MongoDB索引
创建索引
db.books.ensureIndex{{number:1}}
创建索引同时指定索引的名字
db.books.ensureIndex({number:1},{name:"book_"})
索引使用需要注意的地方
  1. 创建索引的时候注意 1 是正序创建索引-1 是倒序创建索引
  2. 索引的创建在提高查询性能的同事会影响插入的性能 对于经常查询少插入的文档可以考虑用索引
  3. 符合索引要注意索引的先后顺序
  4. 每个键全建立索引不一定就能提高性能呢 索引不是万能的
  5. 在做排序工作的时候如果是超大数据量也可以考虑加上索引 用来提高排序的性能
唯一索引
#则插入相同的 name 值会报错
db.books.ensureIndex({name:-1},{unique:true})
#如果建议唯一索引之前已经有重复数值如何处理
#剔除重复数值
db.books.ensureIndex({name:1},{name:"book_",unique:true,dropDups:true})
其他操作
#强制查询已经建立好的索引
#后一个 name 为索引名,正序倒序依据建立索引的规则,否则会报错
db.books.find({name:"323book"}).hint({name:1})
#查询索引信息和查询状态信息
db.books.find({name:"123book"}).explain()
#批量和精确删除索引
db.runCommand({dropIndexes : "books" , index:"name_-1"})
db.runCommand({dropIndexes : "books" , index:"*"})
数据导入导出
把数据好 testdb 中的 persons 导出
mongoexport -d testdb -c persons -o D:/persons.json
导出其他主机数据库的文档
mongoexport --host 192.168.0.16 --port 37017
导入数据(中断其他操作)
mongoimport --db testdb --collections persons --file d:/persons.json

红番茄
7 声望2 粉丝

« 上一篇
kafka笔记
下一篇 »
Netty笔记