第二章 MongoDB基础知识¶
MongoDB非常强大但很容易上手。
- 文档是MongoDB中数据的基本单元。非常类似于关系型数据库管理系统中的行,但更具表现力。
- 类似的,集合可以看作是一个拥有动态模型的表。
- MongoDB的一个实例可以拥有多个相互独立的数据库,每一个数据库都拥有自己的集合。
- MongoDB到了一个简单单功能强大的JavaScript shell 可用于管理 MongoDB 的实例或数据操作。
2.1 文档¶
文档是MongoDB的核心概念。文档就是键值对的一个有序集。
文档的键是字符串,除了少数例外情况,键可以使用任意utf-8字符
- 键不能包含“\0”空字符。这个字符用于表示键的结尾。(一个斜杠+0)
- .和$具有特殊意义,只能在特定环境中使用。通常,这两个字符是被保留的,如果使用不当,驱动程序会有提示。
MongoDB不但区分类型,还区分大小写,例如,下面两个文档是不同的:
{'foo':3}
{'foo':"3"}
下面两个文档也是不同的:
{'foo':3}
{'Foo':3}
还有一个非常重要的事项需要注意,MongoDB的文档不能有重复的键。例如,下面的文档是非法的:
{'greeting':'hello world','greeting':'hello MongoDB'}
文档中的键值对是有序的: {'x':1,'y':2} 与 {'y':2,'x':1} 是不同的,通常字段顺序并不重要,无须让数据库默认依赖特定的字段顺序。在某些情况下,字段顺序变得非常重要。
2.2 集合¶
集合就是一组文档。如果将MongoDB中的一个文档比喻成关系型数据库中的一行,那么集合就相当于一张表。
2.2.1 动态模型¶
集合是动态模式的,这意味着一个集合里面的文档可以是各式各样的。例如下面两个文档可以存储在一个集合里面:
{'greeting':'hello world'}
{'foo':5}
需要注意的是,上面的文档不光值类型不同(一个是字符串,一个是整数),他们的键也不同。因为集合里面可以放置任何文档,随之而来的一个问题是:还有必要使用多个集合吗? 这的确值得思考:既然没有必要区分不同类型的文档的模式,为什么还需要多个集合呢?
- 如果把各种各样的文档不加区分第放在同一个集合中,无论对开发者还是对管理者来说都是噩梦。开发者要么确保每次查询只返回特性类型的文档,要么让执行查询的应用程序来处理所有不同类型的文档。
- 在一个集合里查询特定类型的文档在速度上也很不划算,分开查询多个集合要快得多。
- 把同种类型的文档放在一个集合中,数据会更加集中。
- 创建索引时,需要使用文档的附加结构。索引是按照集合来定义的。
2.2.2 命名¶
集合使用名称进行命名,集合名可以满足下列条件任何utf-8字符串
- 集合名不能是空字符串""
- 集合不能包含"\0"字符(空字符),这个字符表示集合名的结束。
- 集合名不能以"system."开头,这是为系统保留的前缀。
- 用户创建的集合不能再集合中包含保留关键字符"$",因为某些系统中生成的集合中包含"$",很多驱动程序确实支持在集合中包含该字符。除非你要访问这种系统创建的集合,否则不应该在该集合中包含$。
子集合
组织集合的惯例是使用"."分隔不同命名空间的子集合。例如一个具有博客功能的应用可能包含两个集合。分别是 blog.posts 和 blog.authors 。这是为了使组织结构更清晰。
在MongoDB中,使用子集合来组织数据非常高效,值得推荐。
2.3 数据库¶
在MongoDB中,多个文档组成集合,多个集合组成数据库,一个MongoDB实例可以承载多个数据库,每个数据库用友0个或多个集合。每个数据库都有独立的权限,即使是在磁盘上,不同的数据库也放置再通的文件中。
数据库通过名称标识,这点与集合类似。数据库名可以是满足一下条件的任意utf-8字符串:
- 不能是空字符串
- 不得包含有/、\\、.、"、<、>、..... 基本上只能使用ASCII中的字母和数字。
- 数据库区分大小写,即便是在不区分大小写的文件系统中也是如此。简单起见,数据库名应该全部小写。
- 数据库名最多为64字节。
要记住一点。数据库最终会变成文件系统里的文件,而数据库名就是相对应的文件名。
另外,有一些数据库名是保留的。可以直接访问这些有特殊语义的数据库。
- admin
- local
- config
把数据库名添加到集合前面,得到结合的完全限定名,即命名空间。例如使用cms数据库中的blog.posts集合。这个集合的命名空间就是cms.blog.posts。命名空间的长度不得超过121字节。且在实际红应小于100字节。
2.4 启动MongoDB¶
通常,MongoDB作为网络服务器来运行,客户端可以连接该服务器进行操作。下载MongoDB并解压,运行mongod命令来启动数据库服务器:
$ mongod
mongod在没有参数的情况下会使用默认数据目录/data/db.如果数据目录不存在或者不可读写,服务器会启动失败。
启动时,服务器会打印版本和系统信息,然后等待连接.默认情况下,MongoDB会监听27017端口。
mongod还会启动一个非常基本的http服务器,监听数字比主端口高1000的端口,也就是28017端口,可以访问127.0.0.1:28017端口获取数据库管理信息。
2.5 MongoDB shell简介¶
MongoDB 自带JavaScript shell 可以在shell 中使用命令与MongoDB实例交互。 shell非常有用,通过他可以执行管理操作。检查运行实例,亦或做其他操作。
2.5.1 运行shell
运行mongo启动shell:
$ mongo
启动时,shell 将自动连接MongoDB服务器,须确保mongod已启动。
shell 是一个功能完备的JavaScript解释器,可运行任意JavaScript程序。
2.5.3基本操作¶
1.创建
insert函数可将一个文档添加到集合中。
post = {'title':'blog title'}db.blog.insert(post)查看:
db.blog.find()
2.读取
读取一个记录:
db.blog.findOne()
3.更新
使用update修改博客文章,update至少接受两个参数,第一个是限定条件,第二个是新的文档。
首先修改变量post,增加comment键:
post.comment = []然后执行update操作:
db.blog.update({'title':'update title'},post) db.blog.find()
4.删除
使用remove方法可将数据中永久删除,如果没有任何参数,它会将集合内所有文档删除。它可以接受一个作为限定条件的文旦作为参数
db.blog.remove({'title':'update title'})
2.6 数据类型¶
2.6.1 基本数据类型¶
在概念上, MongoDB的文档与JavaScript中的对象相似,因而可认为它类似于json。
- MongoDB在保留json基本键值特性的基础上,添加了一些其他数据类型:
- null 用于表示空值或不存在的字段。 {'x':null}
- 布尔值, true 、false {'x':true}
- 数值 {'x':3.14}、{'x':NumberInt("3")}、{'x':NumberLong('3')}
- 字符串 {'x':'foobar'}
- 日期 {'x':new Date()}
- 正则表达式 {'x':/foobar/i}
- 数组 {'x':['a','b',3]}
- 内嵌文档 {'x':{1,2,3}}
- 对象id {'x':ObjectId()}
- 二进制数据 !二进制不能直接在shell中使用
- 代码 查询和文档中可以包含任意JavaScript代码
2.6.2 日期¶
创建日期对象时,应使用new Date(),而非Date()。
2.6.4 内嵌文档¶
{'name':'job','address':{'city':'nanning','state':1}}
2.6.5 _id和ObjectId()¶
MongoDB文档必须有一个_id键,这个键可以是任意类型,默认是ObjectId对象,在一个集合里面,每个文档都有唯一的"_id",确保集合里面每个文档都能唯一标识。
id生成方式:
0 1 2 3 4 5 6 7 8 9 10 11
时间戳 机器 PID 计数器
如果插入文档没有id键,系统会自动创建一个。
2.7 使用MongoDB shell¶
shell 可以连接到任意MongoDB实例。在启动shell时指定机器名和端口,就可以连接到一套不同的机器:
$ mongo some-host:30000/myDB
通过--nodb参数启动shell,启动时将不会连接任何数据库:
$ mongo --nodb
启动之后,在需要时运行new Mongo(hostname)命令就可以连接到想要的mongo了:
conn = new Mongo('some-host:30000')
>connection to some-host:30000
db = conn.getDB('myDB')
>dbDB
2.7.2 使用shell执行脚本¶
$ mongo script.js
如果希望使用指定的主机/端口上的mongo运行脚本,需要先指定地址,再跟上脚本文件:
$ mongo --quiet server-1:30000/foo script.js
2.7.3 创建.mongorc.js文件¶
如果某些脚本会被频繁加载,可以将它们添加到mongorc.js文件中,这个文件会在启动shell时自动运行。
例如,我们希望启动成功时让shell显示一句欢迎语,为此,我们在用户主目录下创建一个名为.mongorc.js的文件:
//mongorc.js
var comliment = ['attractive','hello','world']
var index = Math.floor(Math.random()*3)
print('hello world')
为了实用,可以使用这个脚本创建一些自己需要的全局变量,或者是为一个太长的名称创建一个简短的别名,也可以重写内置函数。.mongorc.js最常见的用途之一是移除那些危险的shell辅助函数。可以在这里集中重写这些方法:
var no = function(){
print('not on my watch');
}
//禁止删除数据库
db.dropDatabase = DB.prototype.dropDatabase = no;
//禁止删除集合
DBCollection.prototype.drop = no;
//禁止删除索引
DBCollection.prototype.dropIndex = no;
如果在启动shell时指定--norc参数,就可以禁止加载.mongorc.js。
2.7.4 定制shell 提示¶
略
2.7.5 编辑复合变量¶
略