MongoDB是一个流行的开源文档型数据库,它使用类似 JSON 的文档模型存储数据,这使得数据存储变得非常灵活。
MongoDB 是一个基于文档的 NoSQL 数据库,由 MongoDB Inc. 开发。
MongoDB 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

1.业务应用场景

解决三高需求

  • 高并发,对数据库高并发读写的需求
  • 海量数据,对海量数据的高效率存储和访问的需求
  • 对数据库的高可扩展性和高可用性的需求

2.MongoDB基础

NoSql数据库,MongoDB的记录是一个文档,他是一个由字段和值对

1.数据类型

类型 整数 别名 备注 说明
Double 1 double shell中的数字类型 64位浮点数
String 2 string 字符串类型
Object 3 object 对象类型
Array 4 array 数组类型
Binary data 5 binData shell中不可用 二进制数据类型
Undefined 6 undefined 已过时 未定义类型
ObjectId 7 objectId 对象id类型
Boolean 8 bool 布尔类型
Date 9 date 日期类型
Null 10 null 用于表示空值或者不存在的字段
Regular Expression 11 regex 正则表达式类型
DBPointer 12 dbPointer 已过时
JavaScript 13 javascript JavaScript代码
Symbol 14 symbol shell中不可用,已过时
JavaScript(with scope) 15 javascriptWithScope 带作用域的JavaScript代码
32-bit integer 16 int shell中不可用 32位整数
Timestamp 17 timestamp 时间戳类型
64-bit integer 18 long shell中不可用 64位整数
Decimal128 19 decimal 3.4版本新增
Min key -1 minKey shell中无此类型 最小键
Max key 127 maxKey shell中无此类型 最大键

2.使用MongoDB

1.windows

https://www.mongodb.com/try/download/community

命令行参数启动

mongod –dbpath=..\data\db

配置文件启动

新建config文件夹 conf,在conf文件夹创建mongod.conf文件

1
2
storage:
dbPath:D:\mongodb-win32-x86_64-windows-8.0.0\data\db
1
2
3
4
storage:
dbPath: D:\mongodb-win32-x86_64-windows-8.0.0\data\db
port: 27017
bindIp: 127.0.0.1

2.linux

上传 MongoDB 安装包

将从官网下载好的 mongodb-linux-x86_64-4.0.0.tgz 上传到要安装的服务器的目录中
建议目录为:/data/lib/mongodb

解压 MongoDB 安装包

解压 mongodb-linux-x86_64-4.0.0.tgz 文件

1
2
cd /data/lib/mongodb
tar -zxvf mongodb-linux-x86_64-4.0.0.tgz
创建 MongoDB 必要目录

/usr/local 目录中创建 mongodb 文件夹

1
2
cd /usr/local
mkdir mongodb

mongodb 下创建 datalogs 目录

1
2
3
mkdir data
mkdir logs
touch /usr/local/mongodb/logs/mongodb.log
移动 MongoDB 安装目录

将解压后的 mongodb-linux-x86_64-4.0.0 中的文件全部移动到 /usr/local/mongodb

1
mv mongodb-linux-x86_64-4.0.0/* /usr/local/mongodb
设置 MongoDB 环境变量

打开环境变量文件:

1
vim /etc/profile

在文件中增加以下配置:

1
2
export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB_HOME/bin:$PATH

保存后退出。
使新增的环境变量立即生效:

1
source /etc/profile
添加 MongoDB 配置文件
1
vim /etc/mongodb.conf

添加一下常用配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
#指定数据库路径
dbpath=/usr/local/mongodb/data
#指定MongoDB日志文件
logpath=/usr/local/mongodb/logs/mongodb.log
# 使用追加的方式写日志
logappend=true
#端口号
port=27017
#方便外网访问
bind_ip=0.0.0.0
fork=true # 以守护进程的方式运行MongoDB,创建服务器进程
#auth=true #启用用户验证
#bind_ip=0.0.0.0 #绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定则默认本地所有IP
启动和关闭 MongoDB

进入 bin 目录

1
cd /usr/local/mongodb/bin

启动 MongoDB(-conf 使用配置文件方式启动)

1
mongod -f /etc/mongodb.conf

关闭 MongoDB(-conf 使用配置文件方式关闭 )

1
mongod --shutdown -f /etc/mongodb.conf
创建 MongoDB 数据库及管理员账号

进入mongodb的命令行模式

1
2
cd /usr/local/mongodb/bin
./mongo

切换到 admin 数据库,并创建 root (管理员)用户:

1
2
use admin;
db.createUser({user:'root', pwd:'123456', mechanisms : ["SCRAM-SHA-1"] ,roles:[{role:'root', db:'admin'}]});

创建好账号后,可以选择打开 mongodb.conf 中的 auth=true 授权验证。
验证账号是否授权成功:

1
db.auth("root","123456")

如果返回 ‘1’表示验证成功, 如果是 ‘0’ 表示验证失败

3.数据库的删除和创建

1.创建

use articledb(数据库名)

db 展示当前使用的数据库

1
2
3
4
MongoDB默认的数据库
admin 权限和用户
local 这个数据永远不会复制
config 分片设置

2.删除

db.dropDatabase()

4.集合的创建和删除

相当于传统数据库的表

db.createCollection(name) ===>显示创建

删除集合

db.集合名.drop()

5.文档的增删改查

insert和save

db.集合名.insert 插入新文档时,_id字段会自动生成:

1
2
3
db.collection.insert({
"articleId":1,"content":"good","userId":1001,"createTime":new Date()
})

db.集合名.find()

1
2
3
db.collection.find()
//条件查询
db.collection.find({"userId":1002})

投影查询

1
2
0 为不显示 1 为显示
db.collection.find({},{"content":1,_id:0})

6.通过try catch捕获错误

1
2
3
4
5
6
7
try{
db.collection.insertMany({

})
}catch(e){
print(e)
}

7.文档的更新

db.collection.update({“_id”:”1”},{“name”:”richu”})

1
2
3
db.collection.update({userId:"1001"}, {$set:{content:"test"}})
//批量更新
db.collection.update({_id:"67121a9cb63f7427aa0306b5"}, {$set:{userId:"test"}},{multi:true})

8.删除

db.collection.remove({“_id”:”1”})

1
db.collection.remove({"_id":1}, options)

9.比较操作符

比较操作符有:

操作符 描述 示例
$eq 等于 { age: { $eq: 25 } }
$ne 不等于 { age: { $ne: 25 } }
$gt 大于 { age: { $gt: 25 } }
$gte 大于等于 { age: { $gte: 25 } }
$lt 小于 { age: { $lt: 25 } }
$lte 小于等于 { age: { $lte: 25 } }
$in 在指定的数组中 { age: { $in: [25, 30, 35] } }
$nin 不在指定的数组中 { age: { $nin: [25, 30, 35] } }

查找年龄大于 25 且城市为 “New York” 的文档:

1
db.myCollection.find({ age: { $gt: 25 }, city: "New York" });

10.逻辑操作符

逻辑操作符有:

操作符 描述 示例
$and 逻辑与,符合所有条件 { $and: [ { age: { $gt: 25 } }, { city: "New York" } ] }
$or 逻辑或,符合任意条件 { $or: [ { age: { $lt: 25 } }, { city: "New York" } ] }
$not 取反,不符合条件 { age: { $not: { $gt: 25 } } }
$nor 逻辑与非,均不符合条件 { $nor: [ { age: { $gt: 25 } }, { city: "New York" } ] }

11.元素操作符

元素操作符有:

操作符 描述 示例
$exists 字段是否存在 { age: { $exists: true } }
$type 字段的 BSON 类型 { age: { $type: "int" } }

查找包含 age 字段的文档:

1
db.myCollection.find({ age: { $exists: true } });

12.数组操作符

数组操作符有:

操作符 描述 示例
$all 数组包含所有指定的元素 { tags: { $all: ["red", "blue"] } }
$elemMatch 数组中的元素匹配指定条件 { results: { $elemMatch: { score: { $gt: 80, $lt: 85 } } } }
$size 数组的长度等于指定值 { tags: { $size: 3 } }

查找数组 tags 中包含 “red” 和 “blue” 的文档:

1
db.myCollection.find({ tags: { $all: ["red", "blue"] } });

13.其他操作符

还有一些其他操作符如下:

操作符 描述 示例
$regex 匹配正则表达式 { name: { $regex: /^A/ } }
$text 进行文本搜索 { $text: { $search: "coffee" } }
$where 使用 JavaScript 表达式进行条件过滤 { $where: "this.age > 25" }

查找名字以 “A” 开头的文档:

1
db.myCollection.find({ name: { $regex: /^A/ } });

3.MongoDB进阶

1.索引的创建

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。

这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可能要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构

在 MongoDB 中,常见的索引类型包括:

  • 单字段索引:基于单个字段的索引。
  • 复合索引:基于多个字段组合的索引。
  • 文本索引:用于支持全文搜索。
  • 地理空间索引:用于地理空间数据的查询。
  • 哈希索引:用于对字段值进行哈希处理的索引。

MongoDB使用的是B-tree 而mysql使用的是B+tree

createIndex() 方法基本语法格式如下所示:

1
db.collection.createIndex( keys, options )
  • db:数据库的引用。
  • collection:集合的名称。
  • keys:一个对象,指定了字段名和索引的排序方向(1 表示升序,-1 表示降序)。
  • options:一个可选参数,可以包含索引的额外选项。

options 参数是一个对象,可以包含多种配置选项,以下是一些常用的选项:

  • unique:如果设置为 true,则创建唯一索引,确保索引字段的值在集合中是唯一的。
  • background:如果设置为 true,则索引创建过程在后台运行,不影响其他数据库操作。
  • name:指定索引的名称,如果不指定,MongoDB 会根据索引的字段自动生成一个名称。
  • sparse:如果设置为 true,创建稀疏索引,只索引那些包含索引字段的文档。
  • expireAfterSeconds:设置索引字段的过期时间,MongoDB 将自动删除过期的文档。
  • weights:为文本索引指定权重。
1
db.articledb.createIndex({userId:1})

2.创建哈希索引

从 MongoDB 3.2 版本开始,可以使用哈希索引对字段进行哈希,以支持大范围的数值查找。

1
db.collection.createIndex( { field: "hashed" } )

3.查看索引

使用 getIndexes() 方法可以查看集合中的所有索引:

1
db.collection.getIndexes()

4.删除索引

使用 dropIndex() 或 dropIndexes() 方法可以删除索引:

实例

// 删除指定的索引
db.collection.dropIndex( “indexName” )

// 删除所有索引
db.collection.dropIndexes()

4.业务场景的使用

1.基本业务

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

<!-- MongoDB Driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
</dependency>

配置连接

1
2
3
4
5
6
7
8
9
spring:
data:
mongodb:
database: mydb
host: 192.168.3.11
port: 27017
username: root
password: 123456
authentication-database: admin

实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Data  //lombok 简化开发 不需要写set get
@Document(collection = "comment") //指定文档的名字
@CompoundIndex(def = "{'userid':1,'nickname':-1}") //指定索引 与MongoDB原生写法类似
public class Article implements Serializable {

private String id;
@Field("content") //给字段起别名
private String content;
private Date publishtime;
@Indexed //指明该字段为索引
private String userid;
private String nickname;
private Integer likenum;
private LocalDateTime createTime;

private Integer replynum;
private String state;
private String parentid;
private String articleid;
}

注意:

​ @Document(collection = “comment”) 写collection不要写collation 不然可能会报如下的错误

org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 2 (BadValue): 'Field 'locale' is invalid in: { locale: "comment" }' on server 127.0.0.1:27017. The full response is {"ok": 0.0, "errmsg": "Field 'locale' is invalid in: { locale: \"comment\" }", "code": 2, "codeName": "BadValue"}

service类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Service
public class CommentServiceImpl implements CommentService {
@Autowired
private CommentReposity commentReposity;


@Override
public void Insert(Article comment) {
commentReposity.insert(comment);
}

@Override
public Article find(Integer Id) {
Optional<Article> article = commentReposity.findById(String.valueOf(Id));
Article article1 = article.get();
return article1;
}

}

进行测试

1
2
3
4
5
@Test
public void testFindById(){
Article article = commentService.find(1);
System.out.println(article);
}

2.分页查询业务

CommentReposity

1
2
3
4
public interface CommentReposity extends MongoRepository<Article, String> {
Page<Article> findByParentid(String author, Pageable pageable);

}

service

1
2
3
4
5
//分页查询
@Override
public Page<Article> findByPage(String parentId, Integer pageNo,Integer pageSize) {
return commentReposity.findByParentid(parentId, PageRequest.of(pageNo-1, pageSize));
}

3.mongoTemplate

1
2
3
4
5
6
7
8
9
10
11
@Autowired
private MongoTemplate mongoTemplate;

public void updateCommentLikeNum(String Id) {
//查询条件
Query query = new Query(Criteria.where("_id").is(Id));
//更新条件
Update update = new Update();
update.inc("likenum", 1);
mongoTemplate.updateFirst(query,update,Article.class);
}

添加

1
User save = mongoTemplate.save(user, collectionName);

删除

1
2
3
String collectionName = "springboot";
Criteria idCriteria = Criteria.where("id").is(666);
DeleteResult deleteResult = mongoTemplate.remove(new Query(idCriteria), User.class, collectionName);

5.MongoDB高级

1.副本集

  • 主节点类型
  • 次要(辅助,从)节点

2.副本集的创建

rs.initiate(configuration)

添加副本节点

rs.add("192.168.3.133:27018")

添加仲裁节点

rs.add("192.168.3.133:27019")

rs.slaveOk() 在从节点设置自己作为从节点