关于MongoDB

Mr.zh Lv3

一、 MongoDB相关概念

1
2
# 需知:一切博客文档都应以官网白皮书或者开发手册为主
https://www.mongodb.com/docs/languages/python/pymongo-driver/current/connect/

简介

image-20241206195817379

体系结构

image-20241206200138751

image-20241206200146429

BSON数据类型

1
本质就是json数据的二进制格式

image-20241206200231004

特点

image-20241206200314388

二、 基本使用

安装和启动

1
2
3
4
# 方式一
1.在相关文件夹下创建数据库目录
2.在bin目录下使用命令进行启动
mongod --dbpath=..\data\db
1
2
3
4
5
6
# 方式二
1.在bin目录同级的文件下下创建conf目录,然后在里面新建mongod.conf文件
storage:
dbPath: 数据库目录地址(D:\developer_tools\mongodb\mongodb-win32-x86_64-windows-7.0.15\data\db)
2.然后使用命令启动
mongod -f ..\conf\mongod.conf

三、基本常用命令

1
https://www.mongodb.com/docs/languages/python/pymongo-driver/current/read/specify-a-query/

1. 数据库的操作

image-20241208172808172

创建

1
2
//创建一个新的数据,并且切换到这个数据库(空的数据库,里面没有集合的时候,其实只在内存这块存储,并没有进行持久化)
use (数据库名)

查看

1
2
3
4
5
// 查看当前所有数据库
show dbs;
show databases;
//查看当前正在使用的数据库,默认是test
db;

删除

1
2
// 删除数据库:主要针对已经持久化的数据库而言
db.dropDatabase();

2. 集合的操作

集合的显示创建

1
2
3
4
5
6
7
8
9
10
11
// 创建
// db.createCollection(name) name是想要创建的集合名称
db.createCollection("mycollection");

// 查询
show tables;
show collcetions;

// 删除
// db.集合名字.drop()
db.mycollection.drop();

集合的隐式创建

1
见文档的创建

3. 文档的CRUD

单个文档的插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// comment集合如果不存在,则进行创建
// insertOne方法,传入一个json格式的文档数据
db.comment.insertOne(
{
"articleid":"10000",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
}
);

批量文档的插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// 多个文档的插入(insertMany方法,传入的是一个list)
db.comment.insertMany([
{
"_id":1,
"articleid":"10001",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
},
{
"_id":2,
"articleid":"10002",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
},
{
"_id":3,
"articleid":"10003",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
}
])

// 批量插入中如何中间某一条出现错误,已经插入的数据不会进行回滚,所以在插入的时候可以采用这种写法
try{
db.comment.insertMany([

{
"_id":1,
"articleid":"10001",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
},
{
"_id":2,
"articleid":"10002",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
},
{
"_id":3,
"articleid":"10003",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null,
"flag":1
}
])
}catch(e){
print(e)
}

查询

1
2
3
4
5
6
7
8
// 查询所有
db.comment.find()
// 查询单个
db.comment.findOne();
// 带上query的查询(查询articleid 为 10001的单个数据)
db.comment.findOne({"articleid":"10001"});
// 查询特定的字段(投影查询): 需要的展示的字段为1即可,主键默认进行展示
db.comment.find({"_id":1} , {"_id":1 ,"content":1})

修改

1
2
3
4
5
6
7
8
// 覆盖的修改(replace)
db.comment.replaceOne({"_id":1} , {"articleid":"666"});
// 局部修改(updateOne)
db.comment.updateOne({"_id":2} , {$set:{"articleid":"666"}});
// 批量的修改 (updateMany)
db.comment.updateMany({"articleid":"666"} , {$set:{"content":"牛逼666"}})
// 列值增长的修改
db.comment.updateMany({"articleid":"666"} , {$inc:{"likenum":NumberInt(1)}})

image-20241208192311020

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
1. $set – 设置字段值
作用:将指定字段设置为新的值。如果字段不存在,$set 会创建该字段。
db.comment.updateMany(
{ "articleid": "666" },
{ $set: { "content": "Updated content" } }
);
这个命令将所有 articleid 为 "666" 的文档的 content 字段更新为 "Updated content"。
2. $unset – 移除字段
作用:删除指定字段。如果该字段不存在,则不会做任何操作。
db.comment.updateMany(
{ "articleid": "666" },
{ $unset: { "content": "" } }
);
这个命令会删除所有 articleid 为 "666" 的文档中的 content 字段。
3. $push – 向数组字段添加元素
作用:将一个值添加到数组字段的末尾。如果数组字段不存在,则会创建一个数组。
db.comment.updateMany(
{ "articleid": "666" },
{ $push: { "tags": "newTag" } }
);
这个命令会向所有 articleid 为 "666" 的文档的 tags 数组字段添加 "newTag" 元素。
4. $addToSet – 向数组字段添加唯一值
作用:类似于 $push,但是只有在数组中不存在该值时,才会添加它。避免重复值。
db.comment.updateMany(
{ "articleid": "666" },
{ $addToSet: { "tags": "uniqueTag" } }
);
这个命令会向所有 articleid 为 "666" 的文档的 tags 数组字段添加 "uniqueTag",但如果该值已经存在于数组中,则不会添加。
5. $pop – 移除数组的第一个或最后一个元素
作用:从数组中删除元素,可以删除数组的第一个或最后一个元素。
$pop: 1:删除数组的最后一个元素。
$pop: -1:删除数组的第一个元素。
db.comment.updateMany(
{ "articleid": "666" },
{ $pop: { "tags": 1 } } // 删除数组的最后一个元素
);
这个命令会从所有 articleid 为 "666" 的文档的 tags 数组字段中删除最后一个元素。
6. $pull – 从数组中移除指定的元素
作用:从数组字段中移除指定的元素。
db.comment.updateMany(
{ "articleid": "666" },
{ $pull: { "tags": "oldTag" } }
);
这个命令会从所有 articleid 为 "666" 的文档的 tags 数组字段中删除 "oldTag" 元素。
7. $merge – 将更新的文档合并到另一个集合
作用:将更新后的文档写入指定的集合(可以是相同或不同的集合)。
db.comment.updateMany(
{ "articleid": "666" },
{ $set: { "content": "Updated content" } },
{ upsert: true }
).merge("updated_comments");
这个命令会将所有 articleid 为 "666" 的文档更新后写入到 updated_comments 集合中。
8. $rename – 重命名字段
作用:将一个字段的名称改为新的名称。
db.comment.updateMany(
{ "articleid": "666" },
{ $rename: { "content": "description" } }
);
这个命令会将所有 articleid 为 "666" 的文档中的 content 字段重命名为 description。
9. $currentDate – 设置为当前日期或时间
作用:将指定字段设置为当前日期或时间。
$currentDate: { <field>: { $type: <dateType> } }
dateType 可以是 datetimestamp
db.comment.updateMany(
{ "articleid": "666" },
{ $currentDate: { "lastModified": { $type: "date" } } }
);
这个命令会将所有 articleid 为 "666" 的文档的 lastModified 字段更新为当前日期。

删除

1
2
3
4
5
// 指定条件删除单个,和多个
db.comment.deleteOne({"articleid":"666"})
db.comment.deleteMany({"articleid":"666"})
// 删除所有
db.comment.drop();

4. 文档的复杂查询

统计查询

1
2
3
4
// countDocuments():当你需要 根据特定条件 计算文档数量时,使用 countDocuments()。它会查询并扫描符合条件的文档,返回精确计数。
//estimatedDocumentCount():当你不需要根据查询条件筛选,只需要 获取集合中大致的文档总数 时,使用 estimatedDocumentCount()。它依赖集合的元数据,可以更高效地返回估算结果,适用于无需精确结果的情况。
db.comment.countDocuments();
db.comment.estimatedDocumentCount();

分页查询

1.基本分页查询(skip + limit

MongoDB 提供了 skip()limit() 方法来实现分页:

  • **skip(n)**:跳过前 n 条记录。
  • **limit(m)**:限制返回的文档数量为 m 条。

2.示例:分页查询的基本实现

假设你有一个集合 comment,想要进行分页,每页显示 10 条评论,查询第 2 页的评论数据:

  1. 每页的文档数:pageSize = 10
  2. 页码:pageNumber = 2
  3. 跳过文档数:skip = (pageNumber - 1) * pageSize
1
2
3
4
5
6
7
8
9
10
11
// 假设每页10条数据
const pageSize = 10;
const pageNumber = 2; // 查询第2页数据

// 计算 skip 的值
const skip = (pageNumber - 1) * pageSize;

db.comment.find() // 查询所有文档
.skip(skip) // 跳过前面已显示的记录
.limit(pageSize); // 限制返回的记录数为 pageSize

排序查询

1 表示升序(从小到大,默认的顺序)。

-1 表示降序(从大到小)。

1
2
3
4
5
6
7
8
// 升序排序(按 createdAt 字段从早到晚)
db.comment.find().sort({ "createdAt": 1 });

// 降序排序(按 createdAt 字段从晚到早)
db.comment.find().sort({ "createdAt": -1 });

// 按 createdAt 字段降序,likes 字段升序
db.comment.find().sort({ "createdAt": -1, "likes": 1 });

正则查询

1
2
// 查询content字段中包含天气的所有数据
db.comment.find({content:/天气/})

比较包含查询

  • 比较查询

image-20241208205324412

1
2
// 查询_id 小于等于 2的所有数据
db.comment.find({_id:{$lte:2}})
  • 包含查询

image-20241208205605713

1
2
3
4
5

// 包含查询,查询id在[1,2]里面的所有数据
db.comment.find({_id:{$in:[1,2]}})

db.comment.find({_id:{$nin:[3]}})

条件连接查询

and和or的用法

1
2
3
4
5
// and的用法
db.comment.find({$and:[{likenum:{$gte:NumberInt(10)}} , {likenum:{$lt:NumberInt(11)}}]})

// or的用法
db.comment.find({$or:[{_id:1} , {articleid:"10002"} ]})

5. 常用命令小结

image-20241208210421988

四、索引的使用

单字段索引

image-20241209162236612

复合索引

image-20241209162247844

创建

image-20241209162931713

1
2
3
4
// 索引的创建
db.comment.createIndex({articleid :1})
// 复合索引的创建
db.comment.createIndex({content:1,flag:-1})

查看

1
2
// 索引的查看
db.comment.getIndexes();

删除

1
2
3
4
5
6
7
8
9
// 索引的删除:根据创建的状态
db.comment.dropIndex({'articleid':1})

// 根据索引名称进行删除
db.comment.dropIndex("content_1_flag_-1")

// 删除所有索引
db.comment.dropIndexs()

五、执行计划

1
2
3
// 执行计划
db.comment.find()
db.comment.find({content:/天/}).explain()

image-20241209182714965

1
2
3
kaixia423
fZ0AoiogWAvhoNiB
mongodb+srv://kaixia423:fZ0AoiogWAvhoNiB@cluster0.c6hhx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0
  • Title: 关于MongoDB
  • Author: Mr.zh
  • Created at : 2024-12-06 16:10:08
  • Updated at : 2024-12-09 20:20:01
  • Link: https://github.com/zhyoulove/2024/12/06/关于MongoDB/
  • License: This work is licensed under CC BY-NC-SA 4.0.