了解

文档数据库MongoDB用于记录文档结构的数据,如JSON、XML结构的数据。一条文档就是一条记录(含数据和数据结构),一条记录里可以包含若干个键值对。键值对由键和值两部分组成,键又叫做字段。键值对的值可以是普通值,如字符串、整型等;也可以是其他值,如文档、数据及文档数据

{
GoodName: "战神", // 字符串类型值
Price: 44, // 实数类型值
AddedTime: 2016-3-1, // 日期类型值
Groups["书","it书"] // 数组类型值
{ISBN:"2214323423",Press:"电子工业"} //文档类型值
}

安装

1.下载MongoDB 3.4.4安装包到本机

2.建立安装路径,如D:\MongoDB\data。在D:\MongoDB\data路径下分别创建“\db”和"\log"子路径,

D:\MongoDB\data\db  # 用于存放数据库文件
D:\MongoDB\data\log # 用于存放日志文件(mongod.log)

注意

必须要有data子文件路径,db和log子路径必须在data下面,不然安装完成后,执行MongoDB将会出错

bin路径下执行文件介绍

1.mongob.exe,是MongoDB最核心的服务器端数据库管理软件,不能暴露在公共网络上,主要实现服务器端数据库的数据处理、数据访问管理及其他后台管理,存在于每台数据库服务器上。数据库服务端

2.mongo.exe,客户端shell运行支持程序,为数据库系统管理提供了交互式操作数据库统一界面,也为系统开发人员测试数据库等操作提供了方便。Mongo实质是一个JavaScript代码交互式执行平台

3.mongos.exe,路由管理程序,用于MongoDB分片集群环境下的业务系统访问的路由管理

4.mongostat.exe,MongoDB运行状态监控工具,可以快速查看当前运行的mongod或mongos实例的状态

5.mongotop.exe,监控工具,可以根据时间持续对读写数据进行统计,默认1秒返回一次监控信息。

6.mongodump.exe,以人工执行方式,通过Mongod或Mongos,以二进制形式实现对数据库业务数据的导出备份。

7.mongorestore.exe,以人工执行方式,通过Mongod或Mongos,以二进制形式实现对备份数据的恢复,配合mongodump.exe一起使用

8.mongoexport.exe,在人工执行方式下,以JSON或CSV格式导出数据库数据

9.mongoimport.exe,在人工执行方式下,对mongoexport.exe导出的数据恢复到数据库系统之中。

  1. bsondump.exe,将BSON文件转换为可阅读的格式,如可以把Mongodump生成的输出文件转为JSON格式的可阅读文件
  2. mongofiles.exe,把任何数据类型的独立文件上传到MongoDB数据库中,以GridFS形式分块存储,并可以读取相应文件:MongoDB支持的各种编程语言的API接口都提供类似读写功能
  3. mongooplog.exe,以Oplog轮询的方式实现对远程服务器上的数据,同步到本地服务器上
  4. mongoperf.exe,用来测试磁盘IO性能的工具

开机自启/关闭服务

# 首先进入到mongodb安装目录的bin路径下
D:\Mongo\mongdb\bin>mongod --dbpath "d:\Mongo\mongdb\data\db" --logpath "d:\Mongo\mongdb\data\log\MongoDB.log" --install --serviceName "MongoDB" D:\Mongo\mongdb\bin>net start MongoDB
MongoDB 服务正在启动 .
MongoDB 服务已经启动成功。 # 关闭服务
net stop MongoDB

文档值数据类型

数据类型 描述 举例
null 表示空值或者未定义的对象
布尔值 真或假
32位整数 shell不支持该类型,默认会转换成64位浮点数,也可以使用NumberInt类
64位整数 shell不支持该类型,默认会转换成64位浮点数,也可以使用NumberLong类
64位浮点数 shell中的数字就是这一种类型
字符串 utf-8字符串
符号 shell不支持。它会将数据库中的符号类型的数据自动转换成字符串
对象id 文档的12字节的唯一id,保证一条文档记录的唯一性。可以在服务器端自动生成,也可以在代码端生成,允许程序员自行指定id值
日期 从标准纪元开始的毫秒数
正则表达式 文档中可以包含正则表达式,遵循JavaScript的语法
代码 文档中可以包含JavaScript代码 {"nodeprocess": function()
undefined 未定义
数组 值的集合或者列表
内嵌文档 JSON、XML等文档本身

数据库类型

1.admin数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin数据库中,那么该用户就自动继承了所有数据库的权限

2.local数据库:这个数据库永远不会被负责,可以用来存储本地单台服务器的任意集合

3.config数据库:当MongoDB使用分片模式时,config数据库在内部使用,用于保存分片的信息

4.test数据库:MongoDB安装后的默认数据库,可以用于数据库命令的各种操作,包括测试

mongodb数据库建立相关命令

创建自定义数据库名

use goodsdb

# 如果goodsdb数据库不存在,则新建立数据库,如果存在,则连接数据库,然后可以在该数据库上做各种命令操作

查看数据库

show dbs

// 对于刚刚建立的goodsdb数据库并没有显示出来,原因是goodsdb数据库里没有内容。

统计数据库信息

db.stats()

#
{
"db" : "goodsdb", # 数据库名
"collections" : 0, # 集合数量,刚刚安装为0
"views" : 0, #
"objects" : 0, # 文档对象的个数,所有集合的记录数之和
"avgObjSize" : 0, # 平均每个对象的大小,通过dataSize/objects得到
"dataSize" : 0, # 当前库所有集合的数据大小
"storageSize" : 0, # 磁盘存储大小
"numExtents" : 0, # 所有集合的扩展数据量统计数
"indexes" : 0, # 已建立索引数量
"indexSize" : 0, # 索引大小
"fileSize" : 0, # 文件大小
"ok" : 1
}

删除数据库

use goodsdb
db.dropDatabase() # 显示删除成功
{ "ok" : 1 }

查看当前数据库下的集合名称

db.getCollectionNames()

查看数据库用户角色权限

show roles

增删改查

插入

1.插入一条简单文档

> use goodsdb
switched to db goodsdb > db.goodsbaseinf.insert({name:"go语言",price:32})
WriteResult({ "nInserted" : 1 }) # 插入成功提示 > db.goodsbaseinf.find() # 显示集合内容
{ "_id" : ObjectId("62cc34c636d52f097f472808"), "name" : "go语言", "price" : 32 }

说明

1.insert命令,自动产生一个_id值

2.insert命令可以用过save命令代替。若给save命令指定_id值,则会更新默认的_id值,如db.set1.save({_id:1002,x:"OK"})

3.如果没有goodsbaseinf集合对象,则第一次insert时自动建立集合;若存在集合,则变成多条文档的集合

2.插入一条复杂文档

> db.goodsbaseinf.insert({name:"C语言",bookprice:33.2,adddate:2017-10-1,allow:true,baseinf:{ISBN:1882828121,pr
ess:"清华大学"},tags:["good","book","it","Program"]})
WriteResult({ "nInserted" : 1 }) > db.goodsbaseinf.find()
{ "_id" : ObjectId("62cc34c636d52f097f472808"), "name" : "go语言", "price" : 32 }
{ "_id" : ObjectId("62cc366c36d52f097f472809"), "name" : "C语言", "bookprice" : 33.2, "adddate" : 2006, "allow
" : true, "baseinf" : { "ISBN" : 1882828121, "press" : "清华大学" }, "tags" : [ "good", "book", "it", "Program
] }

3.插入多条文档

> db.goodsbaseinf.insert([{item:"小学教程",name:"小学一年级",price:12},{item:"初中教程",name:"初中一年级",price:15}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})

注意

多条文档一次性插入,利用了insert的原子性事务特征,保证所有插入文档要么插入成功,要么不成功

4.用变量方式插入文档

document=({name:"go语言",price:32})
db.goodsbaseinf.insert(document)

5.有序插入多条文档

>db.goodsbaseinf.insert(
[
{
_id:10,item:"小学教程",name:"小学一年级",price:12
},
{
_id:11,item:"初中教程",name:"初中一年级",price:15
}
],
{ordered:true} # 有序插入设置
)

注意

如数据库中以有"_id:11"记录,那么执行记录时,将失败。不能重复插入。但是当有ordered时,当为true时,一条都不插入,为false时,除了出错记录外,其他记录继续插入

6.自定义写出错确认级别(含insert命令出错返回对象显示)

db.goodsbaseinf.insert(
{
_id:1,item:"小学教程",name:"小学一年级",price:12
},
{
writeConcern: { w: "majority",wtimeout:5000 }
}
)

7.插入单条

db.goodsbaseinf.insertOne(
{
item:"小学教程",name:"小学一年级",price:12
}
)

8.一次性插入多条文档

db.goodsbaseinf.insertMany(
[
{
item:"小学教程",name:"小学一年级",price:12
},
{
item:"初中教程",name:"初中一年级",price:15
}
]
)

查询

1.查询集合所有文档

db.goodsbaseinf.find()

db.goodsbaseinf.find().pretty() # 更好看的格式化输出

2.等价条件查询

db.goodsbaseinf.find(
{name:"go语言"}
)

3.不显示id及值,并指定显示值

# 显示name和price,不显示_id
db.goodsbaseinf.find(
{
name,"go语言"
},
{
name:1,price:1,_id:0 # 0或false不显示指定字段,1或true显示指定字段
}
)

4.嵌套文档查询

db.goodsbaseinf.find(
{
"baseinf.press":"清华大学"
}
)

5.数组查询

# 等价查询某一数组
db.goodsbaseinf.find(
{
tags:["good","book","it","Program"]
}
) # 查询数组里的某一个值
db.goodsbaseinf.find(
{
tags:"good"
}
) # 查询有4个元素的数组
db.goodsbaseinf.find(
{
tags:{$size:4}
}
)

6.查找null值字段,查找指定无值字段

db.goodsbaseinf.insert(
[
{_id:2222,toy:null},
{_id:1112}
]
) # 查找null值字段
db.goodsbaseinf.find(
{_id:2222,toy:null}
) # 查找的值不存在
db.goodsbaseinf.find(
{
_id:1112,toy:{$exists:false}
}
)

7.查找返回值游标操作

# 打印显示游标获取的集合
var showCursor=db.goodsbaseinf.find()
showCursor.forEach(printjson)

8.limit和skip方法查询

# 返回第一条文档
db.goodsbaseinf.find().limit(1) # 显示第3条开始的文档记录
db.goodsbaseinf.find().skip(2)

9.带$in运算符的查询

# 用带$in运算符实现或(or)条件查找
# 查找_id等于12或ObjectId("3123566745123423421")的记录文档
db.goodsbaseinf.find(
{
_id:{
$in:[12,ObjectId("3123566745123423421")]
}
}
)

10.通过查询操作符来查询

操作符 格式 实例 mysql类似语句
小于 {:{$lt:}} db.goodsbaseinf.find({price:{$lt:15}}) where price<15
小于等于 {:{$lte:}} db.goodsbaseinf.find({price:{$lte:15}}) where price<=15
大于 {:{$gt:}} db.goodsbaseinf.find({price:{$gt:15}}) where price>15
大于等于 {:{$gte:}} db.goodsbaseinf.find({price:{$gte:15}}) where price>=15
不等于 {:{$ne:}} db.goodsbaseinf.find({price:{$ne:15}}) where price!=15
与(and) db.goodsbaseinf.find({name:"xx",price:12}) where name="xx" and price=12
或(or) {$or:[{key1:value1},{key2:value2},...]} db.goodsbaseinf.find({$or:[{name:"xx"},{price:12}]}) where name="xx" or price=12
模糊匹配 查询以固定值结尾的 db.goodsbaseinf.find({name:{$regex:/语文$/}}) where name like "%语言"
查询以固定值开头的 db.goodsbaseinf.find({name:{$regex:/^C语言/}}) where name like "C语言%"
查询以固定值的任意部分 db.goodsbaseinf.find({name:{$regex:/C/}}) where name like "%C%"

11.区间条件查找

# 查询价格范围大于3小于33的值,可用于文档数值字段,也可以用于数组字段
db.goodsbaseinf.find(
{
price:{$gt:3,$lt:33}
}
)

更新

1.update命令参数

参数名称 说明
query update的查询条件,类似sql update查询where子句后面的查询条件
update update的更新对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询set子句后面的更新内容
upsert 可选,如果不存在update的记录,是否插入objNew;true为插入,默认是false,不插入
multi 可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
writeConcern 可选,自定义写出错确认级别
collation 可选,指定特定国家语言的更新归类规则

返回值:

更新成功,返回WriteResult({"nUpdated":n})对象

更新失败,返回结果中包含WriteResult.writeConcernError对象字段内容

2.修改一条简单文档

# 将购物单1修改为购物单2
use goodsdb db.order.insert(
{
title:"商品购物单1",
amount:35,
}
) # 改订单名称
db.order.update(
{title:"商品购物单1"},
{$set:{title:"商品购物单2"}}
) # 修改数值
db.order.update(
{title:"商品购物单2"},
{$inc:{amount:5}} # $inc做加法运算,加5
) # 修改titlss为title
db.order.update({_id:10,{$rename:{"titlss":"title"}}}) # 删除一个字段
db.order.update(
{
_id:10
},
{
$unset:{unit:"元"}
}
) # 将$min给出的值与当前文档字段值进行比较,当给定值较小时则修改当前文档值为给定值
db.order.update(
{
_id:10
},
{
$min;{amount:50}
}
) # 将$max给出的值与当前文档字段值进行比较,当给定值较大时则修改当前文档值为给定值
db.order.update(
{
_id:10
},
{
$max;{amount:50.5}
}
) # 用ISODate更新当前文档时间字段的值
db.order.update(
{
_id:11
},
{
lasttime: ISODate("2019")
}
)

3.修改一条文档里的数组和嵌套文档

db.order.update(
{
_id:12
},
{
$set:{
# 采用下标的方式来指定要修改的对象
# 数组采用索引,从0开始
"detail.1":{name:"大米",price:40},
# 文档采用取key的方式
"overview.address": "天津市和平区"
}
}
)

4.多文档修改

# 修改所有面粉价格小于30的文档记录,把面粉价格改为40
db.order.update(
{
"detail.name":"面粉","detail.price":{$lte:30}
},
{
$set:{
"detail.1":{name:"面粉",price:40}
}
},
{
multi:true
}
)

5.增加文档字段

# update命令在特定情况下,可以增加文档的字段,甚至实现insert命令功能。这个特定条件是要修改的文档没有要修改的字段,而且update命令带upsert选项

db.order.update(
{
_id:10
},
{
$set:{"detail.0":{name:"西瓜",price:10},unit:"元"}
},
{
upsert:true
}
)

6.自定义写确认级别

# 当update命令在5秒内没有执行完成时,取消该命令操作,并返回错误值
db.order.update(
{
item:""
},
{
$set:{title:"测试",price:50}
},
{
multi:true,
writeconcern:{w: "majority", wtimeout:5000}
}
)

7.3个简化的修改命令

db.collection.updateOne()

db.collection.updateMany()

db.collection.replaceOne()

删除

1.删除参数说明

参数 说明
必选,设置删除文档条件
justOne: 可选,false为默认值,删除符号条件的所有文档;true删除符合条件的一条文档
writeConcern: 可选,自定义写出错确认级别
collation: 可选,指定特定国家语言的删除归类规则

返回值:

删除成功,返回WriteResult({"nRemoved":n})对象。

删除失败,返回结果中会包含WriteResult.writeConcernError对象字段内容(跟writeConern配合使用)

2.删除一个集合里的所有文档记录

db.tests.remove({})

3.删除整个集合包括索引

db.tests.drop()

4.删除符合条件的所有文档记录

# 删除价格大于3的所有文档记录
db.tests.remove(
{
price:{$gt:3}
}
)

5.自定义写出错确认级别

# 删除价格小于3的所有文档记录,当时间超过5秒时,或者副本集大多数已完成该命令执行时,就中断该命令的执行,返回该命令的操作结果
db.tests.remove(
{
price:{$lt:3}
},
{
writeConern: {w: "majority", wtimeout:5000}
}
)

6.删除满足条件的单个文档记录

# 删除价格大于3的第一个文档记录
db.tests.remove(
{
price:{$gte:3}
},
{
justOne:true
}
)

7.删除含特殊语言符号的文档记录

db.tests.remove(
{
item:"cafe",price:{$lte:20}
},
{
justOne:true
},
{
cllation:{locale: "fr", strength:1}
}
)

索引

MongoDB数据库自动为集合_id建立唯一索引,可以避免重复插入同一_id的文档记录

单一字段(键)索引

语法:db.collection_name.createIndex({:})

命令说明:对一个集合文档的键建立索引,key为键名,n=1为升序,n=-1为降序

1.对单一键建立索引

db.books.createIndex(
{name:1}
)

2.嵌套文档单字段索引

db.books.insert(
{
name:"故事",
price:30,
tags:{press:"x出版社",call:"18222223321"}
}
)
db.books.createIndex({"tags.press":1})

字段唯一索引

语法:db.collection_name.createIndex({:,:,....},{unique:true})

命令说明:对一个或多个字段建立唯一索引。key为键名,n=1为升序,n=-1为降序

1.字段值唯一索引

db.books.createIndex({name:1}, {unique:true})

2.多字段索引

db.books.createIndex(
{
price:1,color:-1
}
)

3.多字段唯一索引

db.books.createIndex({name:1,price:1},{unique:true})

文本索引

语法:db.collection_name:createIndex({:"text",:"text2",...})

命令说明:在集合里,为文本字段内容的文档建立文本索引

1.基本文档索引

db.books.createIndex({name:"text"})

2.指定权重文本索引

db.books.createIndex(
{
name:"text",
price:"text"
},
{
weigths:{name:10}, # 为name指定索引权重
name:"TextIndex" # 默认情况下,price权重为1
}
)

3.通配符文本索引

db.books.createIndex({"$**":"text"})

hash索引

语法:db.collection_name.createIndex({key:"hashed"})

命令说明:key为含有哈希值的键

1.建立哈希索引

db.collection.createIndex({_id:"hashed"})

hashed索引不支持多字段索引

hashed会把浮点数的小数部分自动去掉,所以对浮点数字段进行索引时,要注意该特殊情况

hashed不支持唯一索引

索引相关的其他方法

db.collection.dropIndex(index)  # 移除集合指定的索引功能。index参数为指定需要删除的集合索引名,可用getIndexes()函数获取集合的所有索引名称

db.collection.dropIndexes()  # 移除一个集合的所有索引功能

db.collection.getIndexes()   # 返回一个指定集合的现有索引描述信息的文档数组

db.collection.reIndex()  # 删除指定集合上所有索引,并重新构建所有现有索引,在具有大量数据集合的情况下,该操作将大量消耗服务器的运行资源,引起运行性能急剧下降等问题的发生。

db.collection.totalIndexSize()  # 提供指定集合索引大小的报告信息

mongodb(2022)的更多相关文章

  1. 2022年官网下安装MongoDB最全版与官网查阅方法(5.0.6)

    一.下载安装 1.百度搜索,找到官网,或直接访问:https://www.mongodb.com/ 2.寻找下载位置,双击下载. 3.找到本地位置,双击执行,进入欢迎界面,选择next. 4.勾选协议 ...

  2. mongodb 副本集+分片集群搭建

    数据分片节点#192.168.114.26mongod --shardsvr --replSet rsguo --port 2011 --dbpath=/data/mongodb/guo --logp ...

  3. SpringBoot集成MongoDB之导入导出和模板下载

    前言 自己很对自己在项目中集成MongoDb做的导入导出以及模板下载的方法总结如下,有不到之处敬请批评指正! 1.pom.xml依赖引入 <!-- excel导入导出 --> <de ...

  4. CA周记 - Build 2022 上开发者最应关注的七大方向主要技术更新

    一年一度的 Microsoft Build 终于来了,带来了非常非常多的新技术和功能更新.不知道各位小伙伴有没有和我一样熬夜看了开幕式和五个核心主题的全过程呢?接下来我和大家来谈一下作为开发者最应关注 ...

  5. SpringBoot之MongoDB附件操作

    前言 近期自己针对附件上传进一步学习,为了弥足项目中文件上传的漏洞,保证文件上传功能的健壮性和可用性,现在我将自己在这一块的心得总结如下: 一.pom.xml依赖的引入 <dependency& ...

  6. MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建

    前言: 前面的四个章节我们主要讲解了MongoDB的相关基础知识,接下来我们就开始进入使用.NET7操作MongoDB开发一个ToDoList系统实战教程. MongoDB从入门到实战的相关教程 Mo ...

  7. 万字详解,吃透 MongoDB!

    本文已经收录进 JavaGuide(「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识.) 少部分内容参考了 MongoDB 官方文档的描述,在此说明一下. MongoDB ...

  8. ASP.NET Core开发者指南(2022版路线图)

    ASP.NET Core开发者指南 2022年 ASP.NET Core 开发者指南: 在下面,您可以看到一个图,说明可以采用的路径以及要成为ASP.NET Core开发人员所想要学习的库.我将此图作 ...

  9. 7&的2022年终总结

    7&的2022年终总结 文章目录 7&的2022年终总结 1.前言 2.技术 3.生活 4.展望未来 博客搬家的需要: var code = "49d515c3-0238-4 ...

  10. 【翻译】MongoDB指南/聚合——聚合管道

    [原文地址]https://docs.mongodb.com/manual/ 聚合 聚合操作处理数据记录并返回计算后的结果.聚合操作将多个文档分组,并能对已分组的数据执行一系列操作而返回单一结果.Mo ...

随机推荐

  1. [转帖]JVM——内存区域:运行时数据区域详解

    https://www.jianshu.com/p/cded765cfd1b 关注:CodingTechWork,一起学习进步. 引言   我们经常会被问到一个问题是Java和C++有何区别?我们除了 ...

  2. [转帖]分享一个Navicat16最新版永久试用的办法

    https://zhuanlan.zhihu.com/p/614621302 新建bat,就叫 navicat无限试用.bat @echo off echo Delete HKEY_CURRENT_U ...

  3. Oracle AWR学习之二-利用ChatGPT编写一键获取AWR报告的脚本

    Oracle AWR学习之二-ChatGPT提升效率之n 背景 之前生成awr报告比较麻烦, 想着能够一键生成. 再辅以部分shell或者是python处理就可以进行细致的分析. 这一块其实还是比较简 ...

  4. [转帖]armv6、armv7、armv7s、armv8、armv64及其i386、x86_64区别

    ARM处理器指令集 一. 苹果模拟器指令集: 指令集 分析 i386 针对intel通用微处理器32架构的 x86_64 针对x86架构的64位处理器 i386|x86_64 是Mac处理器的指令集, ...

  5. [转帖]一次python服务的性能优化经历

    https://juejin.cn/post/7208708762265616421 问题背景: ​ 在我们的业务中,有一些推荐的场景会需要走到集团研究院的算法推荐服务,对一些用户进行个性化的课件推荐 ...

  6. Oracle 查询用户下表名,表列数,表行数,表大小的SQL

    最近想分析下数据库的信息, 然后写了这个SQL. 比较lowB一些. 因为Oracle的 deferred_segment_creation 参数的影响. 很多表如果是0行,那么是不会创建extent ...

  7. element-ui中Select 选择器列表内容居中

    <el-select class="my-el-select" v-model="tenantCont" placeholder="请输入机构标 ...

  8. 设计模式学习-使用go实现中介者模式

    中介模式 定义 优点 缺点 适用范围 代码实现 参考 中介模式 定义 中介模式(Mediator):用一个中介对象来封装一系列的对象交互.中介者使个各对象不需要显示的相互引用,从而使其藕合松散,而且可 ...

  9. 从嘉手札<2023-11-13>

    1. 很多时候 成功并不等同于成长 成功是很多因素复合形成的一种结果 而并不等同于一个人阅历的丰富.认知的提高 2. 我一直认为 世界不属于投机者 也不属于堕落者 信念感在这个大数据泛滥.碎片化汹涌的 ...

  10. SpringCloud-Gateway搭建保姆级教程

    一.网关介绍 1.什么是网关? 使⽤服务⽹关作为接⼝服务的统⼀代理,前端通过⽹关完成服务的统⼀调⽤ 2.⽹关可以⼲什么? 路由:接⼝服务的统⼀代理,实现前端对接⼝服务的统⼀访问 过滤:对⽤户请求进⾏拦 ...