第二章 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.postsblog.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.2 MongoDB客户端

如果想查看db当前指向那个库可以使用db命令:

db

选择数据库:

>use foobar
>db
foobar

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.3 数组

数组是一组值,它既能做有序对象,也能做无序对象:

{'titings':['pie',123]}

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.1 shell 小贴士

可以使用help查看帮助:

>help()

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 编辑复合变量

2.7.6 集合命名注意事项

如果对您有用,请我喝杯咖啡吧。

赞助扫码::
../../../_images/apay.jpg ../../../_images/pay_wechat.png