MongoDB安装与快速入门
MongoDB是一个基于分布式文件存储的数据库,介于关系型数据库与非关系型数据库之间,是非关系数据库中功能最丰富,最像关系型数据库的。它支持的结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是它支持的查询非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系型数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB术语与关系型SQL对比
{'name':'杨过', 'gender':'男'}
{'name':'风清扬', 'age': 55, 'gender': '男'}
{'name':'令狐冲', 'age': 32, 'gender': '男', 'partner':'小龙女'}
{'name':'乔峰', 'age':40, 'gender': '男', 'kongfu':'响龙十八掌'}
文档是MongoDB中的核心概念。文档就是键值对的一个有序集。每种编程语言表示文档的方法不太一样,但是大多数编程语言都有一些通用的数据结构,比如映射map、散列hash、字典等。例如:
{"name": "风清扬", "age": 54, "gender":"男"}
MongoDB不但区分类型,还区分大小写,比如下面的两个文档是不同的:
# 区分大小写
{"name": "terminator"}
{"Name": "terminator"}
# 区分类型
{"age": "54"}
{"age": 54}
MongoDB中的键不能重复,例如下面的文档是非法的:
{"name":"zhangsanfeng", "name":"zhangwuji", "age":56}
MongoDB中键/值是有顺序的,例如,下面的两个文档也是不同的:
{"name":"linqingxia", "age": 52}
{"age": 52, "name":"linqingxia"}
集合就是有一组文档组成,相当于关系型数据库中表的概念。而文档就相当于关系型数据库表中的一行记录。
集合是动态模式的,这就意味着集合里的文档可以是各式各样的,不需要每个文档具有相同的键。例如:
{"name":"张无忌", "kongfu":"九阳神功", "age": 25}
{"department":"账务部"}
需要注意的是,上面的文档有不同值的类型、键的个数和键的名称完全不相同。因为集合里面可以放置任何文档,随之而来的一个问题是:还有必要使用多个集合吗?这里有几个重要的原因:
如同关系型数据库中的表一样,集合使用名称进行标识。集合名称可以是满足下面条件的任意UTF-8字符串。
组织集合的一种惯例是使用"."来分隔不同命名空间的子集合。例如,一个具有博客功能的应用可能包含两个集合,分别是blog.posts和blog.authors。这样划分是为了使组织结构更加清晰,这里的blog集合(这个集合甚至不需要存在)跟它的子集合没有任何关系。
虽然子集合没有任何特别的属性,但它们非常有用,因而很多的MongoDB工具都使用子集合。
在MongoDB中,使用子集合来组织数据非常高效,值得推荐使用子集合。
在MongoDB中,多个文档组成集合,而多个集合则可以组成数据库。一个MongoDB实例可以承载多个数据库,每个数据库可以包含0个或多个集合。每个数据库拥有独立的权限,即便是在磁盘上,不同的数据库在物理上也存储在不同的文件中。
和关系型数据库一样,通过名称来标识数据库名,数据库的命名可以是满足下面条件的任意UTF-8字符串:
数据库最终对应系统中的文件,而数据库名称就是文件的名称,这也是数据库名称命名需要这么多限制的根本原因。
另外,MongoDB保留了一些数据库名称,这些数据库有特殊的用途:
在Ubuntu下MongoDB的安装非常简单,无需下载源文件,可以直接使用`apt-get`命令进行安装。
(base) hadoop@node1:~$ sudo apt-get install mongodb
MongoDB shell
# 查看mongodb的版本信息
(base) hadoop@node1:~$ mongo -version
MongoDB版本
# 查看mongodb启动状态
(base) hadoop@node1:~$ sudo systemctl status mongodb
MongoDB启动状态
(base) hadoop@node1:~$ sudo systemctl stop mongodb
(base) hadoop@node1:~$ sudo systemctl start mongodb
默认情况下MongoDB是随ubuntu启动的,可以通过以下命令查看
(base) hadoop@node1:~$ pgrep mongo -l
pgrep mongo -l
$ sudo apt-get --purge remove mongodb mongodb-clients mongodb-server
MongoDB自带了JAVAScript shell, 可以在shell中使用命令行与MongoDB实时交互。shell非常有用,通过它可以执行某些对MongoDB的管理操作,检查运行的实例等。
运行`mongo`启用shell:
mongo命令启动shell
启动shell时,shell将自动连接MongoDB服务器,在启动MongoDB shell前,确保mongod服务已启动。shell是一个功能完备的JavaScript解释器,可以运行任意的JavaScript程序,例如:
> a = 100
100
> a/5
20
> Math.sin(Math.PI/2)
1
> new Date()
ISODate("2020-07-30T06:15:30.924Z")
> "Hi MongoDB, Hi Python".replace("Python","Mongo");
Hi MongoDB, Hi Mongo
> function factorial(n) {
... if(n<=1) return 1;
... return n*factorial(n-1);
... }
> factorial(5)
120
MongoDB shell可以运行任意的JavaScript脚本听上去很酷,不过它的真正强大之处在于,它是一个独立的MongoDB客户端,在shell启动时,它会连接到MongoDB服务器的`test`数据库,并将数据库连接赋值给全局变量db。这个全局变量是通过shell访问MongoDB的主要入口点。
例如下面的命令:
# 查看db当前指向哪个数据库
> db
test
# 列出当前MongoDB中有哪些数据库
> show dbs
admin 0.000GB
config 0.000GB
crm 0.000GB
local 0.000GB
# 切换数据库
> use crm
switched to db crm
在shell中查看或操作数据会用到4个基本操作:创建、读取、更新和删除。即通常所说的`CRUD`。
`insert`可以将一个文档添加到集合中。
> use movie
switched to db movie
> actor = {"name":"乔峰","age":40, "movie":"天龙八部","author":"金庸","kongfu":"响龙十八掌","department":"丐帮"}
{
"name" : "乔峰",
"age" : 40,
"movie" : "天龙八部",
"author" : "金庸",
"kongfu" : "响龙十八掌",
"department" : "丐帮"
}
> db.movie.actors.insert(actor)
WriteResult({ "nInserted" : 1 })
> db.movie.actors.find()
{ "_id" : ObjectId("5f226c49a20e34cfb8a8ab33"), "name" : "乔峰", "age" : 40, "movie" : "天龙八部", "author" : "金庸", "kongfu" : "响龙十八掌", "department" : "丐帮" }
> actor = {"name":"段誉","age":34, "movie":"天龙八部","author":"金庸","kongfu":"六脉神剑","department":"大理国"}
{
"name" : "段誉",
"age" : 34,
"movie" : "天龙八部",
"author" : "金庸",
"kongfu" : "六脉神剑",
"department" : "大理国"
}
> db.movie.actors.insert(actor)
WriteResult({ "nInserted" : 1 })
> db.movie.actors.find()
{ "_id" : ObjectId("5f226c49a20e34cfb8a8ab33"), "name" : "乔峰", "age" : 40, "movie" : "天龙八部", "author" : "金庸", "kongfu" : "响龙十八掌", "department" : "丐帮" }
{ "_id" : ObjectId("5f226d25a20e34cfb8a8ab34"), "name" : "段誉", "age" : 34, "movie" : "天龙八部", "author" : "金庸", "kongfu" : "六脉神剑", "department" : "大理国" }
>
find()和fineOne()都可以用于查询集合中的文档。若只需要查看一个文档使用findOne()。
> db.movie.actors.findOne()
{
"_id" : ObjectId("5f226c49a20e34cfb8a8ab33"),
"name" : "乔峰",
"age" : 40,
"movie" : "天龙八部",
"author" : "金庸",
"kongfu" : "响龙十八掌",
"department" : "丐帮"
}
可以使用update更新文档,update至少需要两个参数:第一个是限定条件(限定集合中待更新的文档),第二个是新的文档。
> actor.comments = ['很厉害','妹子好多啊']
[ "很厉害", "妹子好多啊" ]
> db.movie.actors.update({"name":"段誉"}, actor)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.movie.actors.find()
{ "_id" : ObjectId("5f226c49a20e34cfb8a8ab33"), "name" : "乔峰", "age" : 40, "movie" : "天龙八部", "author" : "金庸", "kongfu" : "响龙十八掌", "department" : "丐帮" }
{ "_id" : ObjectId("5f226d25a20e34cfb8a8ab34"), "name" : "段誉", "age" : 34, "movie" : "天龙八部", "author" : "金庸", "kongfu" : "六脉神剑", "department" : "大理国", "comments" : [ "很厉害", "妹子好多啊" ] }
>
使用remove方法可以将文档从数据库中永久删除。如果没有任何参数,它会将集合内的所有文档全部删除。它也可以接受一个作为限定条件的文档作为参数。例如:
> db.movie.actors.remove({"name":"段誉"})
由于MongoDB的内容比较多,接下来会分几篇文章讲解MongoDB的数据类型、查询操作等内容。