MongoDB 最全攻略(二)

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 在介绍 MongoDB 之前,我先介绍一下业务开发的时候遇到的痛点,以便大家对它有一个更加清晰的认识! 最近在用数据库存储数据的时候发现这么一个坑,例如从消息队列中监听消息的时候,原来的做法是将监听的消息数据存储在数据库,以便好对异常消息数据进行追溯,消息内容使用text类型存储,起初因为数据内容很短,没啥毛病,但是当随着业务的扩展,收到的消息内容越来越长,最后发现数据库中的text字段类型根本没法存储,于是在这个时候,就开始考虑采用更加合适的数据库来存储这种消息数据!
3.3.3、创建一个业务数据库普通用户

如果你想创建一个业务数据库普通用户,例如只能访问test_db数据库,并且只负责数据的増查改删。

# 创建或者切换数据库到test_db
use test_db
# 创建一个test用户,并且只能访问test_db,对表只有读写权限
db.createUser(
{
  user: "test",
  pwd: "test",
  roles: [ { role: "readWrite", db: "test_db" } ]
})
3.3.4、验证用户是否可以正常登录

对于刚刚创建的用户,我们怎么验证它是否能正常登录呢?命令也很简单!

db.auth("test","test")

如果返回是1表示鉴权正常!

3.3.5、查询当前数据库用户信息

查询创建的用户,命令也很简单!

# 查看创建的用户
show users
3.3.6、修改用户密码

有些时候,我们会忘记密码,可通过如下方式进行修改!

#修改用户密码
db.changeUserPassword("username", "xxxxx")
3.3.7、删除用户

如果某个用户需要停用,可通过如下方式进行删除

#切换指定数据库
use test_db
#删除用户
db.dropUser('test')
3.3.8、删除数据库

如果某个数据库需要停用,可通过如下方式进行删除(只有超级管理员有权限删除)

#切换指定数据库
use test_db
#删除数据库
db.dropDatabase()

3.4、创建集合

MongoDB 并无这个概念,而对应的定义叫:集合,我们在关系型数据库中看到的表数据,在 MongoDB 中被定义为:文档,MongoDB 也被很多人成为文档数据库

在关系型数据库中,表数据是一行一行的存储,但是在 MongoDB 中,可能不是这样,如果你存储的 json 非常复杂,嵌套很深,那么在 MongoDB 中存储的行数,可能非常深,存储的时候类似我们在页面看到的父子表结构!

3.4.1、创建一个集合

MongoDB 中使用 createCollection() 方法来创建集合。

语法格式:

db.createCollection(name, options)

参数说明:

  • name: 要创建的集合名称
  • options: 可选参数, 指定有关内存大小及索引的选项

例如,在 test_db 数据库中创建 tb_user 集合:

# 切换到test_db数据库
use test_db
# 创建 tb_user 集合
db.createCollection("tb_user")
#输出结果
{ "ok" : 1 }

如果要查看已有的集合,可以使用show collections命令!

show collections

下面是带有几个关键参数的createCollection()的用法,下面命令表示:创建固定集合tb_user,整个集合空间大小6142800KB, 文档最大个数为10000

db.createCollection("tb_user", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )

在 MongoDB 中,很多时候不需要手动创建集合。当你插入一个文档时,MongoDB 会自动创建集合!

# 向集合tb_user 插入一条文档数据
db.tb_user.insert({"name" : "张三"})
#查询集合
show collections
# 输出结果
tb_user
3.4.2、删除一个集合

MongoDB 中使用 drop() 方法来删除集合。

语法格式:

db.collection.drop()

例如,删除在 test_db 数据库中 tb_user 集合:

# 切换到test_db数据库
use test_db
# 创建 tb_user 集合
db.tb_user.drop()
#输出结果
true

3.4、创建文档

创建文档,类似我们在关系型数据库中,将数据插入到数据库,操作也很简单!

3.4.1、插入文档

MongoDB 使用 insert()save() 方法向集合中插入文档。

语法如下:

db.COLLECTION_NAME.insert(document)
db.COLLECTION_NAME.save(document)
  • save():如果_id主键存在则更新数据,如果不存在就插入数据。
  • insert():若插入的数据主键已经存在,则会抛异常,提示主键重复,不保存当前数据。

例如,在test_db数据库的tb_user集合中,插入一条数据

db.tb_user.insert(
{
    name:"张三",
    age:18,
    gender:"男",
    tags: ['宅男', '技术控', '脱发严重']
})

如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。

查看已插入文档,命令如下:

#查询tb_user集合中的数据
db.tb_user.find()
# 输出结果
{ "_id" : ObjectId("6022310f6b5e964b0a5916e6"), "name" : "张三", "age" : 18, "gender" : "男", "tags" : [ "宅男", "技术控", "脱发严重" ] }

当然,你还可以通过save()命令进行插入,如果不指定_id字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。

例如,将张三年龄更新到30岁!

db.tb_user.save(
{
 _id: ObjectId("6022310f6b5e964b0a5916e6"),
    name:"张三",
    age:30,
    gender:"男",
    tags: ['宅男', '技术控', '脱发严重']
})

查看文档

db.tb_user.find()
# 输出结果
{ "_id" : ObjectId("6022310f6b5e964b0a5916e6"), "name" : "张三", "age" : 30, "gender" : "男", "tags" : [ "宅男", "技术控", "脱发严重" ] }
3.4.2、更新文档

MongoDB 提供了 update()save() 方法来更新集合中的文档。

语法格式如下:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。

例如,将张三年龄更新到22岁!

db.tb_user.update({'name':'张三'},{$set:{'age':22}})

查询已更新的数据

db.tb_user.find()
# 输出结果
{ "_id" : ObjectId("602235216b5e964b0a5916e8"), "name" : "张三", "age" : 22, "gender" : "男", "tags" : [ "宅男", "技术控", "脱发严重" ] }

以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置multi参数为true

db.tb_user.update({'name':'张三'},{$set:{'age':22}},{multi:true})
3.4.3、删除文档

MongoDB 中的remove()函数是用来移除集合中的数据

语法格式如下:

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)
  • query :(可选)删除的文档的条件。
  • justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
  • writeConcern :(可选)抛出异常的级别。

例如,删除姓名为张三的用户

db.tb_user.remove({'name':'张三'})

查询数据是否被删除

db.col.find()
#结果为空
3.4.4、查询文档

MongoDB 查询文档使用 find() 方法。

语法格式如下:

db.collection.find(query, projection)
  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:

db.col.find().pretty()

首先我们插入几条数据,插入结果如下:

12.jpg

例如,查询一个性别为的用户信息

#单个条件查询,类似 sql语句中的 gender = '男'
db.tb_user.find({"gender":"男"})

查询一个性别为,姓名为张三的用户

#多条件查询,类似 sql语句中的 gender = '男' and name = '李四'
db.tb_user.find({"gender":"男","name":"李四"})

查询一个性别为 或者 姓名为张三的用户

#多条件查询,类似 sql语句中的 gender = '男' or name = '李四'
db.tb_user.find({$or:[{"gender":"男"},{"name": "李四"}]})

查询一个性别为 或者 姓名为张三,同时年龄大于30的用户

#多条件查询,类似 sql语句中的 age > 30 and ( gender = '男' or name = '李四')
db.tb_user.find({"age": {$gt:30}, $or:[{"gender":"男"},{"name": "李四"}]})
3.4.5、分页查询文档

如果需要分页查询集合数据,可以使用limit()skip()函数,其中limit()表示读几条数据,skip()表示从第几条数据开始。

#从集合中的第三行数据开始,读2条数据返回
db.tb_user.find({}).limit(2).skip(3)
3.4.6、文档排序

和关系型数据库一样,MongoDB 可以使用sort()方法进行排序,通过参数指定排序的字段,并使用 1-1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。

例如,查询tb_user文档,按照age进行升序排序!

db.tb_user.find({}).sort({"age":1})

3.5、创建索引

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

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

3.5.1、创建索引

MongoDB 使用 createIndex() 方法来创建索引,语法格式如下:

db.collection.createIndex(keys, options)

语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可!

例如,给tb_user文档中的age创建一个索引!

db.tb_user.createIndex({"age":1})

创建索引是一个比较耗时的动作,我们还可以通过参数配置,在后台创建索引。

db.tb_user.createIndex({"age":1}, {background: true})

通过在创建索引时加background:true的选项,让创建工作在后台执行!

3.5.2、查看索引

MongoDB 提供了getIndexes()方法,可以进行查看索引。

例如,查询tb_user集合中的索引

db.tb_user.getIndexes()
3.5.3、删除索引

不在需要的索引,我们可以将其删除。删除索引时,可以删除集合中的某一索引,可以删除全部索引。

语法格式:

db.COLLECTION_NAME.dropIndex("INDEX-NAME")

例如,删除集合tb_user集合中的age索引:

#查询索引
db.tb_user.getIndexes()
#输出结果
[
 {
  "v" : 2,
  "key" : {
   "_id" : 1
  },
  "name" : "_id_",
  "ns" : "test_db.tb_user"
 },
 {
  "v" : 2,
  "key" : {
   "age" : 1
  },
  "name" : "age_1",
  "ns" : "test_db.tb_user"
 }
]

删除对应的age_1索引!

db.tb_user.dropIndex("age_1")

四、客户端

对于任何一款数据库,如果没有可视化界面操作,在开发的时候,可以说极其不方便,下面推荐一款小编经常使用的一款客户端。

  • Robo 3T(免费、轻量级) ,可以访问官网获取

13.jpg

Studio 3T(全面,收费),访问官网地址获取

14.jpg

其中小编采用的是第二款,整体的体验比Robo 3T要一点,两者功能都比较齐全!

在使用的时候,可以根据个人喜爱进行选择!

五、重要的一步

网上发现很多 mongodb 被黑,使大家将目光投向了mongodb 的权限控制。

其实 mongodb 本身有一套完备的 RBAC 权限控制体系,这次被黑基本都是没有遵照 mongodb 的生产环境部署手册部署的结果。

我们平时玩一玩 mongodb 习惯了不设置用户名密码,当我们的数据库放到公网时,由于我们也没有设置用户名密码,任何人都可以随便访问,而且由于我们没有开启授权访问,使得任何登录到 mongodb 服务器的用户都拥有最高权限!

一些居心不良的人发现,就可以把我们的数据拷走,删除我们的数据库,从而勒索赎金!

再次提醒各位同学,别学会所有的技能,大门还一直开着,还抱怨我方防御塔怎么一直被摧毁!

以上文CentOS7安装为例,修改/etc/mongod.conf,在security部分添加如下配置,开启授权访问!

security:
    authorization: enabled

修改完成之后,重启 mongodb 服务

#重启服务
systemctl restart mongod

六、小结

本文主要围绕 MongoDB 的使用,从环境配置、数据库使用,再到客户端工具选用,做了简单的介绍,可能有的地方总结的不到位,欢迎各位网友批评指出!

在下篇文章中,我们会详细的介绍SpringBootMongoDB的整合实践!

七、参考

1、MongoDB 官方文档

2、菜鸟教程 - mongodb

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
2月前
|
存储 JSON NoSQL
MongoDB 教程
10月更文挑战第9天
42 0
|
7月前
|
存储 分布式计算 NoSQL
MongoDB的简介和安装(在服务器上)
MongoDB的简介和安装(在服务器上)
133 0
|
7月前
|
NoSQL Java MongoDB
MongoDB笔记
MongoDB笔记
54 0
|
存储 NoSQL JavaScript
MongoDB必备知识点全面总结(二)
MongoDB必备知识点全面总结
358 0
MongoDB必备知识点全面总结(二)
|
存储 JSON NoSQL
MongoDB必备知识点全面总结(三)
MongoDB必备知识点全面总结
316 0
MongoDB必备知识点全面总结(三)
|
存储 SQL NoSQL
MongoDB必备知识点全面总结(四)
MongoDB必备知识点全面总结
270 0
MongoDB必备知识点全面总结(四)
|
存储 JSON NoSQL
MongoDB必备知识点全面总结(一)
MongoDB必备知识点全面总结
669 0
MongoDB必备知识点全面总结(一)
|
存储 JSON NoSQL
mongodb笔记
mongodb笔记
423 0
|
NoSQL Java atlas
『MongoDB』免费领取官方提供的Atlas云托管MongoDB
📣读完这篇文章里你能收获到 - 官方提供的云托管MongoDB - 终身免费的测试账号
469 1
『MongoDB』免费领取官方提供的Atlas云托管MongoDB
|
存储 消息中间件 NoSQL
MongoDB 最全攻略(一)
在介绍 MongoDB 之前,我先介绍一下业务开发的时候遇到的痛点,以便大家对它有一个更加清晰的认识! 最近在用数据库存储数据的时候发现这么一个坑,例如从消息队列中监听消息的时候,原来的做法是将监听的消息数据存储在数据库,以便好对异常消息数据进行追溯,消息内容使用text类型存储,起初因为数据内容很短,没啥毛病,但是当随着业务的扩展,收到的消息内容越来越长,最后发现数据库中的text字段类型根本没法存储,于是在这个时候,就开始考虑采用更加合适的数据库来存储这种消息数据!
MongoDB 最全攻略(一)