mongoDB 学习
一、mongoDB简介
- MongoDB是一个开源、高性能、无模式的文档型数据库,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。
- MongoDB支持的数据结构非常松散,是一种类似于 JSON 的格式叫 BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。
- MongoDB中的记录是一个文档,它是一个由字段和值对(fifield:value)组成的数据结构。即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。
二、mongoDB 特点
Mysql 和 MongoDb 的一些名词的对比:
| Mysql | MongoDB |
|---|---|
| 数据库(Database) | 数据库(Database) |
| 表(table) | 集合(collection) |
| 行(row) | 文档(Document) |
| 字段(column) | 域(field) |
| 索引(index) | 索引(index) |
| 表连接(table joins) | 不支持表连接,通过嵌入式文档来替代多表连接 |
| 主键(primary key) | 主键(primary key) |
BOSN 的数据类型,此处盗用一张网上的图(侵权删)
MongoDB的特点:
- 高性能:
MongoDB提供高性能的数据持久性。特别是对嵌入式数据模型的支持减少了数据库系统上的I/O活动
- 高可用性:
MongoDB的复制工具称为副本集(replica set),它可提供自动故障转移和数据冗余
- 高扩展性:
MongoDB提供了水平可扩展性作为其核心功能的一部分。分别将数据分布在一组集群的机器上。
- 丰富的查询支持:
MongoDB支持丰富的查询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等。
- 其他特点:如无模式(动态模式)、灵活的文档模型
**
三、安装启动MongoDB
这里演示如何在linux上安装启动MongoDB,并通过工具连接
安装环境和工具:
- centos 7
- finalshell
- navicat 12.1
1,安装依赖
sudo yum install libcurl openssl
2,获取下载链接
3,开始下载
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.1.tgz
4,解压到指定目录
mkdir /usr/local/mongodb
tar -zxvf mongodb-linux-x86_64-4.0.10.tgz -C /usr/local/mongodb
5,新建数据存储目录,修改配置文件
cd /usr/local/mongodb/
# 数据存储目录
mkdir -p data/db
# 日志存储目录
mkdir logs
新建并修改配置文件:
vim mongod.conf
配置文件可直接拷贝使用(这个文件的格式可以用在线YAML格式化一下,避免出现问题 www.bejson.com/validators/…)
systemLog:
#MongoDB发送所有日志输出的目标指定为文件
# #The path of the log file to which mongod or mongos should send all diagnostic logging information
destination: file
#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
path: "/usr/local/mongodb/logs/mongod.log"
#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
logAppend: true
storage:
#mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod
##The directory where the mongod instance stores its data.Default Value is "/data/db"
dbPath: "/usr/local/mongodb/data/db"
journal:
#启用或禁用持久性日志以确保数据文件保持有效和可恢复
enabled: true
processManagement:
#启用在后台运行mongos或mongod进程的守护进程模式
fork: true
net:
#服务实例绑定的IP,默认是localhost
bindIp: 0.0.0.0
6,启动MongoDB
cd /usr/local/mongodb/mongodb-linux-x86_64-4.0.10
bin/mongod -f ./mongod.conf
出现一下提示表示启动成功
可以查看下进程是否启动:
7,使用 Navicat 链接
四、MongoDB语法
1,数据库操作
1.1,创建数据库
- 可以使用以下命令创建数据库,如果不创建,mongodb默认使用的是 test 库
# 如果存在则使用,如果不存在则创建
use liuqiuyiTest
注意,此时创建完数据库后,使用 show dbs 默认是看不到,因为此时这个数据库还在内存中,只有在我们往里面创建集合或者插入文档的情况下,mongodb 才会将这个库写入到磁盘中
db.liuqiuyiTest.insert({"name":"liuqiuyi"});
在使用 show dbs 命令就能看到这个数据库了
1.2,删除数据库
可以使用以下命令删除数据库:
db.dropDatabase()
删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。
再次查看发现刚刚创建的数据库被删除了
2,集合操作
集合的创建分为 显式创建 和 隐式创建:
- 显式创建:直接使用命令创建集合
- 隐式创建:创建文档的时候顺带创建集合
2.1 显式创建集合
创建一个 collA 的集合
db.createCollection("collA")
可以通过以下命令查询创建的集合
show collections;
2.2 隐式的创建集合
插入文档的同时,会隐式的创建集合,例如:
db.collB.insert({"name":"liuqiuyi"})
此时查看db中的所有集合,发现collB 被隐式的创建了
2.3 删除无用的集合
通过以下命令可以删除集合
# collA 表示集合名
db.collA.drop()
3,文档操作
3.1 插入文档
- 单条插入文档:
db.collA.insert({"name":"liuqiuyi"});
查看集合中所有文档可以到,mongoDb会对插入的文档增加一个名为 _id 的主键,当然你也可以自己指定
- 批量插入文档:
db.collA.insertMany([{"name":"张三"},{"name":"李四"}])
3.2 查询文档
- 查询集合中所有的文档
db.collA.find();
- 带条件查询文档
# 查询集合文档中,name=liuqiuyi的
db.collA.find({"name":"liuqiuyi"});
- 如果有多个满足条件的,只取第一条,类似于关系型数据库中的 limit 1 ,可以使用 findOne
db.collA.findOne({"name":"liuqiuyi"});
- 如果一个文档中有很多字段,我只想查询出某一个字段,其它字段不显示,可以在查询语句后面写上对应的条件,例如:
# 这里表示查询 name=liuqiuyi 的文档,只显示 name 字段,注意 1 是数字类型
db.collA.find({"name":"liuqiuyi"},{"name":1});
3.3 更新文档
- 覆盖修改:修改某个字段之后,会将之前整个文档替换为修改后的字段
我们将第一条的数据,age 修改为 22
# 将 _id = 5f5e1ece6db32411440004a3 的文档,age 值修改为 22,注意要使用ObjectId()
db.collA.update({_id:ObjectId("5f5e1ece6db32411440004a3")},{"age":22});
- **局部修改:**只修改某个字段的值,其它字段不受影响
# 和刚刚的语句类似,只是加了个 $set 标识
db.collA.update({_id:ObjectId("5f5e1ece6db32411440004a3")},{$set:{"age":23}});
- 如果更新条件有多个符合的文档,某认只会更新第一个,如果想将所有满足条件的全部更新,需要加上 multi:true 参数
# 将文档中 name = liuqiuyi 的所有数据,age 修改为 25 ,并且不影响其它字段的值
db.collA.update({"name":"liuqiuyi"},{$set:{"age":25}},{multi:true});
- 如果想对某一个数值字段进行增加或者减少,可以使用 $inc 运算符实现
# 对 id 为 5f5e1ece6db32411440004a3 的 age 字段进行 +1 的操作
db.collA.update({"_id":ObjectId("5f5e1ece6db32411440004a3")},{$inc:{age:1}});
如果是减少,则为 {$inc:{age:-1}}
3.4 删除文档
- 根据 _id 删除某一个文档
db.collA.remove({"_id":ObjectId("5f5e1f1c6db32411440004a4")})
如果删除的条件对应多个文档,也可以直接删除掉,不需要添加额外的参数
- 删除所有的文档
db.collA.remove({});
3.5 统计查询
- 统计当前集合中有多少个文档
db.collA.count();
也可以带条件统计
# 统计当前集合中,name = liuqiuyi 的文档的个数
db.collA.count({"name":"liuqiuyi"});
3.6 分页查询
集合中有4个文档
- 使用 limit 参数查询前几条数据
# 查询前两条数据
db.collA.find().limit(2);
如果我想查询第3、4两条数据,那么只使用 limit 就无法完成了,这时需要用到 skip 关键字
- 跳过前两条,查询第3、4条数据
db.collA.find().skip(2).limit(2);
3.7 排序查询
- 单条件排序查询
# 按照 age 字段升序
db.collA.find().sort({"age":1})
如果是降序,则将排序条件修改为:sort({"age":-1})
- 多条件排序
# 先按照 age 升序,在按照 name 进行降序
db.collA.find().sort({"age":1},{"name":-1})
3.8 正则表达式查询
mongoDB 中可以通过 JS 的正则表达式写法查询,常用的有:
- 查询包含某一字段的文档
# 查询文档中name字段包含 liu 这个字段的,注意不要使用引号
db.collA.find({"name":/liu/});
- 查询某一字段开头的文档
# 查询文档中 name 字段 以 张 开头的
db.collA.find({"name":/^张/});
- 查询某一字段结尾的文档
# 查询文档中name字段以 yi 结尾的
db.collA.find({"name":/yi$/});
- 忽略大小写匹配
# 查询文档中name字段包含 liu 这个字段的, i 表示 忽略大小写
db.collA.find({"name":/liuqiuyi/i});
3.9 比较查询
# 查询文档中 age 值 大于 20 的
db.collA.find({"age":{$gt:20}});
常见的运算符有:
| 运算符 | 含义 |
|---|---|
| $gt | 大于 |
| $lt | 小于 |
| $gte | 大于等于 |
| $lte | 小于等于 |
| $ne | 不等于 |
3.10 包含查询
包含查询使用 $in 操作符,类似关系型数据库中的in关键字
# 在文档中查找 name 在 in 条件的
db.collA.find({"name":{$in:["liuqiuyi","Liuqiuyi","张三"]}})
不包含使用 $nin 操作符
db.collA.find({"name":{$nin:["liuqiuyi","Liuqiuyi","张三"]}})
3.11 条件连接查询
mongodb 是不支持 join 查询的,所以这里只介绍两个连接查询,and 和 or
- and 多条件查询
# 查询 age >= 22 and age <= 24
db.collA.find({$and:[{"age":{$gte:22}},{"age":{$lte:24}}]});
# 查询 name = liuqiuyi and age = 25
db.collA.find({$and:[{"name":"liuqiuyi"},{"age":25}]})
- or 条件查询
# 查询 name = Liuqiuyi or name = liuqiuyi
db.collA.find({$or:[{"name":"Liuqiuyi"},{"name":"liuqiuyi"}]});
五、索引
mongoDB 和 mysql 类似,也是可以对集合中的文档创建索引的,以此来加快查询速度
5.1 索引的类型
单字段索引
- mongo支持在文档的单个字段上创建 升序/降序 索引,这种索引被称为单字段索引。对于单个字段的索引,索引键的排序顺序并不重要。因为mongoDB可以在任何方向上遍历索引
复合索引
- 在多个字段上创建索引,就是复合索引。复合索引中列出的字段顺序就是排序的顺序。例如:{name: 1,age: -1} 表示先按照 name 正序排序,在按照 age 倒序排序
其它索引
- 文本索引
- 哈希索引
其它索引本次不讨论
5.2 索引的管理
索引的查看
通过如下命令查看集合中所有的索引:
# 查询集合中所有的索引。collA 是集合名
db.collA.getIndexes();
可以看到和mysql一样,主键默认有一个索引
上面的参数表示的含义为:
| 字段名 | 含义 |
|---|---|
| V | mongoDb 的索引版本号 |
| key | _id 表示对应的索引列,后面的 1 表示正序,如果是 -1 表示降序 |
| name | 索引名称。默认为字段加上 _ |
| ns | name space ,表示对应的集合 |
索引的创建
- 创建索引的语法为:
# 在 collA 集合中对 name 字段创建一个 升序索引。如果为 -1 就是降序索引
db.collA.createIndex({"name":1});
创建完成后在次查询集合中所有的索引
db.collA.getIndexes();
- 也可以创建符合索引
# 对 collA 集合创建复合索引,先按照 age 升序,在按照 date 降序
db.collA.createIndex({"age":1,"date":-1});
- 创建索引时的更多选项
创建索引时,可以指定 options ,常见的 options 参数列表有:
| 参数 | 参数类型 | 描述 |
|---|---|---|
| background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,默认值为 false |
| unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false |
| expireAfterSeconds | int | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间 |
| weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重 |
以 unique 参数举例:
# 对 collA 集合中的 name 字段创建 升序索引,并且是唯一索引
db.collA.createIndex({"name":1},{"unique":true});
索引的删除
- 删除指定的索引
# 删除指定的索引。这里删除的是 collA 集合中 name = 1 的索引
db.collA.dropIndex({"name":1})
也可以通过索引名称删除对应的索引
# 先查询集合中所有的索引
db.collA.getIndexes();
# 删除指定名称的索引
db.collA.dropIndex("age_-1")
- 删除所有的索引
# 删除 collA 集合中所有的索引
db.collA.dropIndexes();
但是 _id 的索引是无法删除的
5.3 索引的使用
执行计划
类似于 mysql ,我们也可以使用 explain 关键字来查看我们的查询语句是否使用了索引
# 查询 collA 集合中,age=24 and name=Liuqiuyi 的文档,并使用explain 查看执行计划
db.collA.find({$and:[{"age":24},{"name":"Liuqiuyi"}]}).explain();
上图中查看到我们并未使用索引,那么我们加上索引之后,在使用 explain 查询一下
# 对 collA 集合创建复合索引,按照age升序,name升序
db.collA.createIndex({"age":1,"name":1});
执行刚刚的查询语句,查看执行计划
六、和 java 整合
见另一篇文档 mongoDB和java整合