在介绍 MongoDB 之前,我先介绍一下业务开发的时候遇到的痛点,以便大家对它有一个更加清晰的认识!
最近在用数据库存储数据的时候发现这么一个坑,例如从消息队列中监听消息的时候,原来的做法是将监听的消息数据存储在数据库,以便好对异常消息数据进行追溯,消息内容使用text类型存储,起初因为数据内容很短,没啥毛病,但是当随着业务的扩展,收到的消息内容越来越长,最后发现数据库中的text字段类型无法很好的支持查询,于是在这个时候,就开始考虑采用更加合适的数据库来存储这种消息数据!
在经过一番讨论之后,对于这种 json 类型的消息数据的存储,大家一致认为采用 MongoDB 是最佳的选择!
据官方介绍,MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富、最像关系数据库的一款高性能的 NoSQL 数据库。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。
其中的文档类似于 JSON 对象。字段值可以包含其他文档、数组及文档数组,数据结构的支持非常灵活!
的确,在使用的过程当中,正如所介绍的,数据的存储和查询,性能极快,而且很好的满足我们的需求!
话不多说,下面我们就一起来了解一下,这款数据库应该如何使用!
在学习它之前,我们需要先搭建好环境,MongoDB 的安装也非常简单!
如果你是 Windows 平台,MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制,安装基本是傻瓜式的操作,登录 MongoDB 官网并且下载安装包,然后一步一步的操作即可!

生产环境基本都是 Linux 平台,为了和生产保持一致,小编采用的服务器是CentOS7,安装过程也比较简单!
sudo vim /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
sudo yum install -y mongodb-org
mongod.conf允许远程连接#编辑mongod.conf
vim /etc/mongod.conf
#将net:bindIp: 127.0.0.1 改为 0.0.0.0
net:
bindIp:0.0.0.0
#开启服务
systemctl start mongod
#其他服务
#关闭服务
systemctl stop mongod
#重启服务
systemctl restart mongod
#开机自启
systemctl enable mongod
至此,环境配置已经完成!
MongoDB 的数据操作,是开发人员接触最频繁的部分,第一次使用的时候,你会发现它和我们传统使用的 sql 脚本命令完全不同,但是又类似,下面我们就一起来深入的了解下!
进入 MongoDB 服务很简单,输入如下命令即可进入!
mongo
例如,在CentOS里面输入命令之后,进入的服务界面如下:

MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
输入如下命令,可以查询数据库列表
#查询数据库列表
show dbs
#命令输出结果:
admin
config
local
可以看到,当前 MongoDB 有三个数据库!
输入如下命令,可以切换到admin数据库
use admin
输入db命令,还可以查询当前数据库
db
默认的情况下,是没有用户的,也无法操作数据库,因此我们需要创建一个用户,同时给他分配权限!
创建一个用户、密码都是admin的用户,同时给这个用户分配userAdminAnyDatabase角色,指定的数据库为admin!
#创建一个admin用户
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})
其中字段含义如下:
userAdminAnyDatabase,只在 admin 数据库中可用。角色在 MongoDB 中,代表着某个用户是否有权限访问数据库或者操作数据库,理解这点非常重要!
MongoDB 角色定义如下:
| 角色类型 | 名称 | 描述 |
|---|---|---|
| admin数据库角色 | readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
| admin数据库角色 | readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
| admin数据库角色 | userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
| admin数据库角色 | dbAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限 |
| admin数据库角色 | clusterAdmin | 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限 |
| admin数据库角色 | root | 只在admin数据库中可用,超级账号,超级权限 |
| 数据库管理角色 | dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
| 数据库管理角色 | userAdmin | 允许用户向system.users集合写入,可以在指定数据库里创建、删除和管理用户 |
| 数据库用户角色 | read | 允许用户读取指定数据库 |
| 数据库用户角色 | readWrite | 允许用户读写指定数据库 |
如果你想创建一个不受访问限制的超级用户,赋予root角色即可!
#创建超级用户
db.createUser(
{
user:"root",
pwd:"root",
roles:["root"]
}
)
如果你想创建一个业务数据库普通用户,例如只能访问test_db数据库,并且只负责数据的増查改删。
# 创建或者切换数据库到test_db
use test_db
# 创建一个test用户,并且只能访问test_db,对表只有读写权限
db.createUser(
{
user: "test",
pwd: "test",
roles: [ { role: "readWrite", db: "test_db" } ]
})
对于刚刚创建的用户,我们怎么验证它是否能正常登录呢?命令也很简单!
db.auth("test","test")
如果返回是1表示鉴权正常!
查询创建的用户,命令也很简单!
# 查看创建的用户
show users
有些时候,我们会忘记密码,可通过如下方式进行修改!
#修改用户密码
db.changeUserPassword("username", "xxxxx")
如果某个用户需要停用,可通过如下方式进行删除
#切换指定数据库
use test_db
#删除用户
db.dropUser('test')
如果某个数据库需要停用,可通过如下方式进行删除(只有超级管理员有权限删除)
#切换指定数据库
use test_db
#删除数据库
db.dropDatabase()
MongoDB 并无表这个概念,而对应的定义叫:集合,我们在关系型数据库中看到的表数据,在 MongoDB 中被定义为:文档,MongoDB 也被很多人成为文档数据库!
在关系型数据库中,表数据是一行一行的存储,但是在 MongoDB 中,可能不是这样,如果你存储的 json 非常复杂,嵌套很深,那么在 MongoDB 中存储的行数,可能非常深,存储的时候类似我们在页面看到的父子表结构!
MongoDB 中使用 createCollection() 方法来创建集合。
语法格式:
db.createCollection(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
MongoDB 中使用 drop() 方法来删除集合。
语法格式:
db.collection.drop()
例如,删除在 test_db 数据库中 tb_user 集合:
# 切换到test_db数据库
use test_db
# 创建 tb_user 集合
db.tb_user.drop()
#输出结果
true
创建文档,类似我们在关系型数据库中,将数据插入到数据库,操作也很简单!
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" : [ "宅男", "技术控", "脱发严重" ] }
MongoDB 提供了 update() 和 save() 方法来更新集合中的文档。
语法格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
例如,将张三年龄更新到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})
MongoDB 中的remove()函数是用来移除集合中的数据
语法格式如下:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
例如,删除姓名为张三的用户
db.tb_user.remove({'name':'张三'})
查询数据是否被删除
db.col.find()
#结果为空
MongoDB 查询文档使用 find() 方法。
语法格式如下:
db.collection.find(query, projection)
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
db.col.find().pretty()
首先我们插入几条数据,插入结果如下:

例如,查询一个性别为男的用户信息
#单个条件查询,类似 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": "李四"}]})
如果需要分页查询集合数据,可以使用limit()和skip()函数,其中limit()表示读几条数据,skip()表示从第几条数据开始。
#从集合中的第三行数据开始,读2条数据返回
db.tb_user.find({}).limit(2).skip(3)
和关系型数据库一样,MongoDB 可以使用sort()方法进行排序,通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
例如,查询tb_user文档,按照age进行升序排序!
db.tb_user.find({}).sort({"age":1})
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB 在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
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的选项,让创建工作在后台执行!
MongoDB 提供了getIndexes()方法,可以进行查看索引。
例如,查询tb_user集合中的索引
db.tb_user.getIndexes()
不在需要的索引,我们可以将其删除。删除索引时,可以删除集合中的某一索引,可以删除全部索引。
语法格式:
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要一点,两者功能都比较齐全!
在使用的时候,可以根据个人喜爱进行选择!
网上发现很多 mongodb 被黑,使大家将目光投向了mongodb 的权限控制。
其实 mongodb 本身有一套完备的 RBAC 权限控制体系,这次被黑基本都是没有遵照 mongodb 的生产环境部署手册部署的结果。
我们平时玩一玩 mongodb 习惯了不设置用户名密码,当我们的数据库放到公网时,由于我们也没有设置用户名密码,任何人都可以随便访问,而且由于我们没有开启授权访问,使得任何登录到 mongodb 服务器的用户都拥有最高权限!
一些居心不良的人发现,就可以把我们的数据拷走,删除我们的数据库,从而勒索赎金!
再次提醒各位同学,别学会所有的技能,大门还一直开着,还抱怨我方防御塔怎么一直被摧毁!
以上文CentOS7安装为例,修改/etc/mongod.conf,在security部分添加如下配置,开启授权访问!
security:
authorization: enabled
修改完成之后,重启 mongodb 服务
#重启服务
systemctl restart mongod
本文主要围绕 MongoDB 的使用,从环境配置、数据库使用,再到客户端工具选用,做了简单的介绍,可能有的地方总结的不到位,欢迎各位网友批评指出!
在下篇文章中,我们会详细的介绍SpringBoot和MongoDB的整合实践!
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景 最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。 在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记
目录一、ESP32简单介绍二、ESP32Wi-Fi模块介绍三、ESP32Wi-Fi编程模型四、ESP32Wi-Fi事件处理流程 五、ESP32Wi-Fi开发环境六、ESP32Wi-Fi具体代码七、ESP32Wi-Fi代码解读6.1主程序app_main7.2自定义代码wifi_init_sta()八、ESP32Wi-Fi连接验证8.1测试方法8.2服务器模拟工具sscom58.3测试代码8.4测试结果前言为了开发一款亚马逊物联网产品,开始入手ESP32模块。为了能够记录自己的学习过程,特记录如下操作过程。一、ESP32简单介绍ESP32是一套Wi-Fi(2.4GHz)和蓝牙(4.2)双模解决方
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?
📝学技术、更要掌握学习的方法,一起学习,让进步发生👩🏻作者:一只IT攻城狮。💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。❤️《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址👉🏻SpringCloud入门实战系列不迷路👈🏻:SpringCloud入门实战(一)什么是SpringCloud?SpringCloud入门实战