1.MongoDB安装和配置
MongoDB 的官方下载站是 http://www.mongodb.org/downloads,可以去上面下载最新的安装
程序下来。在下载页面可以看到,它对操作系统支持很全面,如 OS X、 Linux、 Windows、 Solaris
都支持,而且都有各自的 32 位和 64 位版本。这里掩饰的版本为2.0.6。
注意:
1. MongoDB 2.0.6 Linux 版要求 glibc 必须是 2.5 以上,所以需要先确认操作系统的 glibc 的版
本。
2. 在 32 位平台 MongoDB 不允许数据库文件(累计总和)超过 2G,而 64 位平台没有这个
限制。
怎么安装MongoDB 数据库呢?下面将分别介绍 Windows 和 Linux 版本的安装方法
1.1 Windows 平台的安装
步骤一: 下载 MongoDB
url 下载地址:
步骤二: 设置 MongoDB 程序存放目录
将其解压到c:\,再重命名为 mongo,路径为 c:\mongo
步骤三: 设置数据文件存放目录
在 c:盘建一个 db 文件夹,路径 c:\db
步骤四: 启动 MongoDB 服务
进入cmd 提示符控制台,c:\mongo\bin\mongod.exe --dbpath=c:\db
C:\mongo\bin>C:\mongo\bin\mongod --dbpath=c:\db
Sun Apr 10 22:34:09 [initandlisten] MongoDB starting : pid=5192 port=27017 dbpat
h=d:\data\db 32-bit
** NOTE: when using MongoDB 32 bit, you are limitedto about 2 gigabytes of data
** see http://blog.mongodb.org/post/137788967 /32-bit-limitations
** with --dur, the limit is lower
……
Sun Apr 10 22:34:09 [initandlisten] waiting for connections on port 27017
Sun Apr 10 22:34:09 [websvr] web admin interface listening on port 28017
MongoDB 服务端的默认监听端口是27017
步骤五: 将 MongoDB 作为Windows 服务随机启动
先创建 C:\mongo\logs\mongodb.log 文件,用于存储 MongoDB 的日志文件, 再安装系统
服务。
C:\mongo\bin>C:\mongo\bin\mongod --dbpath=c:\ db --logpath=c:\mongo\lo
gs\mongodb.log --install
all output going to: c:\mongo\logs\mongodb.log
Creating service MongoDB.
Service creation successful.
Service can be started from the command line via 'net start "MongoDB"'.
C:\mongo\bin>net start mongodb
Mongo DB 服务已经启动成功。
C:\mongo\bin>
步骤六: 客户端连接验证
新打开一个 CMD 输入:c:\mongo\bin\mongo,如果出现下面提示,那么您就可以开始
MongoDB 之旅了
C:\mongo\bin>c:\mongo\bin\mongo
MongoDB shell version: 1.8.1
connecting to: test
>
步骤七: 查看 MongoDB 日志
查看 C:\mongo\logs\mongodb.log 文件,即可对 MongoDB 的运行情况进行查看或排错了,
这样就完成了 Windows 平台的 MongoDB 安装。
1.2 Linux 平台的安装
步骤一: 下载 MongoDB
下载安装包:curl -O http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.6.tgz
步骤二: 设置 MongoDB 程序存放目录
将其解压到/Apps,再重命名为 mongo,路径为/Apps/mongo
步骤三: 设置数据文件存放目录
建立/data/db 的目录, mkdir –p /data/db
步骤四: 启动 MongoDB 服务
/Apps/mongo/bin/mongod --dbpath=/data/db
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db
Sun Apr 8 22:41:06 [initandlisten] MongoDB starting : pid=13701 port=27017 dbpath=/data/db
32-bit
** NOTE: when using MongoDB 32 bit, you are limitedto about 2 gigabytes of data
** see http://blog.mongodb.org/post/137788967 /32-bit-limitations
** with --dur, the limit is lower
……
Sun Apr 8 22:41:06 [initandlisten] waiting for connections on port 27017
Sun Apr 8 22:41:06 [websvr] web admin interface listening on port 28017
MongoDB 服务端的默认连接端口是27017
步骤五: 将MongoDB 作为Linux 服务随机启动
先创建/Apps/mongo/logs/mongodb.log 文件,用于存储 MongoDB 的日志文件
vi /etc/rc.local, 使用 vi 编辑器打开配置文件,并在其中加入下面一行代码
/Apps/mongo/bin/mongod --dbpath=/data/db --logpath=/Apps/mongo/logs/mongodb.log
步骤六: 客户端连接验证
新打开一个 Session 输入:/Apps/mongo/bin/mongo,如果出现下面提示,那么您就可以
开始 MongoDB 之旅了
[root@localhost ~]# /Apps/mongo/bin/mongo
MongoDB shell version: 1.8.1
connecting to: test
>
步骤七: 查看 MongoDB 日志
查看/Apps/mongo/logs/mongodb.log 文件,即可对 MongoDB 的运行状况进行查看或分
析了
[root@localhost logs]# ll
总计0
-rw-r--r-- 1 root root 0 04-08 20:15 mongodb.log
[root@localhost logs]#
以上的几个步骤就 OK 了!! 这样一个简单的 MongoDB 数据库就可以畅通无阻地运行起
来了。
2.数据存储结构
MongoDB 对国内用户来说比较新, 它就像是一个黑盒子,但是如果对于它内部的数据存储了解多一些的话,那么将会很快的理解和驾驭 MongoDB,让它发挥它更大的作用。
MongoDB 的默认数据目录是/data/db,它负责存储所有的 MongoDB 的数据文件。在 MongoDB内部,每个数据库都包含一个.ns 文件和一些数据文件,而且这些数据文件会随着数据量的
增加而变得越来越多。所以如果系统中有一个叫做 foo 的数据库,那么构成 foo 这个数据库的文件就会由 foo.ns,foo.0,foo.1,foo.2 等等组成,具体如下:
[root@localhost db]# ll /data/db/
总计196844
-rw------- 1 root root 16777216 04-15 16:33 admin.0
-rw------- 1 root root 33554432 04-15 16:33 admin.1
-rw------- 1 root root 16777216 04-15 16:33 admin.ns
-rw------- 1 root root 16777216 04-21 17:30foo.0
-rw------- 1 root root 33554432 04-21 17:30 foo.1
-rw------- 1 root root 67108864 04-21 17:30foo.2
-rw------- 1 root root 16777216 04-21 17:30 foo.ns
-rwxr-xr-x 1 root root 6 04-21 17:16 mongod.lock
-rw------- 1 root root 16777216 04-15 16:30 test.0
-rw------- 1 root root 33554432 04-15 16:30 test.1
-rw------- 1 root root 16777216 04-15 16:30 test.ns
drwxr-xr-x 2 root root 4096 04-21 17:30 _tmp
3.启动数据库
MongoDB 安装、配置完后,必须先启动它,然后才能使用它。怎么启动它呢?下面分别展示了 3 种方式来启动实例。
3.1.1 命令行方式启动
如果已经将MongoDB设置为服务则可以掠过该步骤。
MongoDB 默认存储数据目录为/data/db/ (或者c:\data\db), 默认端口 27017,默认 HTTP 端口 28017。当然你也可以修改成不同目录,只需要指定 dbpath 参数: /Apps/mongo/bin/mongod
--dbpath=/data/db
[root@localhost ~]#/Apps/mongo/bin/mongod --dbpath=/data/db
Sun Apr 8 22:41:06 [initandlisten] MongoDB starting : pid=13701 port=27017 dbpath=/data/db
32-bit
……
Sun Apr 8 22:41:06 [initandlisten] waiting for connections on port 27017
Sun Apr 8 22:41:06 [websvr] web admin interface listening on port 28017
3.1.2 配置文件方式启动
如果是一个专业的 DBA,那么实例启动时会加很多的参数以便使系统运行的非常稳定,这样
就可能会在启动时在 mongod 后面加一长串的参数,看起来非常混乱而且不好管理和维护,
那么有什么办法让这些参数有条理呢?MongoDB 也支持同 mysql 一样的读取启动配置文件
的方式来启动数据库,配置文件的内容如下:
[root@localhost bin]# cat /etc/mongodb.cnf
dbpath=/data/db/
启动时加上”-f”参数,并指向配置文件即可
[root@localhost bin]# ./mongod -f /etc/mongodb.cnf
Mon May 28 18:27:18 [initandlisten] MongoDB starting : pid=18481 port=27017
dbpath=/data/db/ 32-bit
……
Mon May 28 18:27:18 [initandlisten] waiting for connections on port 27017
Mon May 28 18:27:18 [websvr] web admin interface listening on port 28017
3.1.3 Daemon 方式启动
大家可以注意到上面的两种方式都慢在前台启动 MongoDB 进程,但当启动 MongoDB 进程
的 session 窗口不小心关闭时,MongoDB 进程也将随之停止,这无疑是非常不安全的,幸好
MongoDB 提供了一种后台 Daemon 方式启动的选择,只需加上一个”--fork”参数即可,这
就使我们可以更方便的操作数据库的启动,但如果用到了”--fork”参数就必须也启用”
--logpath”参数,这是强制的
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db --fork
--fork has to be used with --logpath
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db --logpath=/data/log/r3.log
--fork
all output going to: /data/log/r3.log
forked process: 19528
[root@localhost ~]#
3.1.4 mongod 参数说明
最简单的,通过执行 mongod 即可以启动 MongoDB 数据库服务,mongod 支持很多的参数,
但都有默认值,其中最重要的是需要指定数据文件路径,或者确保默认的/data/db 存在并且
有访问权限,否则启动后会自动关闭服务。Ok,那也就是说,只要确保 dbpath 就可以启动
MongoDB 服务了
mongod 的主要参数有:
●dbpath:
数据文件存放路径,每个数据库会在其中创建一个子目录,用于防止同一个实例多次运
行的 mongod.lock 也保存在此目录中。
●logpath
错误日志文件
●logappend
错误日志采用追加模式(默认是覆写模式)
●bind_ip
对外服务的绑定 ip,一般设置为空,及绑定在本机所有可用 ip 上,如有需要可以单独
指定
●port
对外服务端口。Web 管理端口在这个 port 的基础上+1000
●fork
以后台 Daemon 形式运行服务
●journal
开启日志功能,通过保存操作日志来降低单机故障的恢复时间,在 1.8 版本后正式加入,
取代在 1.7.5 版本中的 dur 参数。
●syncdelay
系统同步刷新磁盘的时间,单位为秒,默认是 60 秒。
●directoryperdb
每个 db 存放在单独的目录中,建议设置该参数。与 MySQL 的独立表空间类似
●maxConns
最大连接数
●repairpath
执行 repair 时的临时目录。在如果没有开启 journal,异常 down 机后重启,必须执行 repair
操作。
3.1.5 连接数据库
现在我们就可以使用自带的 MongoDB shell 工具来操作数据库了. (我们也可以使用各种编程
语言的驱动来使用 MongoDB, 但自带的 MongoDB shell 工具可以方便我们管理数据库)。
新打开一个 Session 输入: /Apps/mongo/bin/mongo,如果出现下面提示,那么您就说明连接
上数据库了,可以进行操作了
[root@localhost ~]# /Apps/mongo/bin/mongo
MongoDB shell version: 1.8.1
connecting to: test
>
默认shell 连接的是本机 localhost 上面的test 库, "connecting to:" 这个会显示你正在使用
的数据库的名称. 想换数据库的话可以用”use mydb”来实现。
4.数据库操作
4.1 插入记录
下面我们来建立一个 test 的集合并写入一些数据. 建立两个对象 j 和 t , 并保存到集合中去.
在例子里“>” 来表示是shell 输入提示符
> j = { name : "mongo" };
{"name" : "mongo"}
> t = { x : 3 };
{ "x" : 3 }
>db.things.save(j);
>db.things.save(t);
> db.things.find();
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x": 3 }
>
有几点需要注意一下:
●不需要预先创建一个集合. 在第一次插入数据时候会自动创建.
●在文档中其实可以存储任何结构的数据, 当然在实际应用我们存储的还是相同类型文
档的集合. 这个特性其实可以在应用里很灵活, 你不需要类似 alter table 语句来修改你
的数据结构
●每次插入数据时候集合中都会有一个 ID, 名字叫_id.
下面再加点数据:
> for( var i = 1; i < 10; i++ ) db.things.save( { x:4, j:i } ); > db.things.find();
{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}
{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}
{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}
{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}
{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}
{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}
{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}
{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}
{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}
{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}
请注意一下, 这里循环次数是 10, 但是只显示到第 8 条, 还有 2 条数据没有显示. 如果想继
续查询下面的数据只需要使用”it”命令, 就会继续显示下面的数据:
{ "_id" : ObjectId("4c220a42f3924d31102bd866"), "x": 4, "j" : 17 }
{ "_id" : ObjectId("4c220a42f3924d31102bd867"), "x": 4, "j" : 18 }
has more
> it
{ "_id" : ObjectId("4c220a42f3924d31102bd868"), "x": 4, "j" : 19 }
{ "_id" : ObjectId("4c220a42f3924d31102bd869"), "x": 4, "j" : 20 }
从技术上讲find() 返回一个游标对象. 但在上面的例子里, 并没有拿到一个游标的变量. 所
以shell 自动遍历游标, 返回一个初始化的 set, 并允许我们继续用it 迭代输出.
当然我们也可以直接用游标来输出, 不过这个是”游标”部分的内容了.
4.2 _id key
MongoDB 支持的数据类型中,_id 是其自有产物,下面对其做些简单的介绍。
存储在 MongoDB 集合中的每个文档 (document)都有一个默认的主键_id,这个主键名称是
固定的,它可以是 MongoDB 支持的任何数据类型,默认是 ObjectId。在关系数据库 schema
设计中,主键大多是数值型的,比如常用的 int 和 long,并且更通常的是主键的取值由数据
库自增获得,这种主键数值的有序性有时也表明了某种逻辑。反观 MongoDB,它在设计之
初就定位于分布式存储系统,所以它原生的不支持自增主键。
_id key 举例说明:
当我们在往一个集合中写入一条文档时,系统会自动生成一个名为_id 的 key.如:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
这里多出了一个类型为 ObjectId 的 key ,在插入时并没有指定,这有点类似 Oracle 的 rowid
的信息,属于自动生成的。
在 MongoDB 中,每一个集合都必须有一个叫做_id 的字段,字段类型默认是 ObjectId ,换句话
说,字段类型可以不是 ObjectId,例如:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
{ "_id" : 3, "name" : "Bill", "age" : 55 }
虽然_id 的类型可以自由指定,但是在同一个集合中必须唯一,如果插入重复的值的话,系统
将会抛出异常,具体如下:
> db.c1.insert({_id:3, name:"Bill_new", age:55})
E11000 duplicate key error index: test.c1.$_id_ dup key: { : 3.0 }
>
因为前面已经插入了一条_id=3 的记录,所以再插入相同的文档就不允许了。
4.3 普通查询
在没有深入查询之前, 我们先看看怎么从一个查询中返回一个游标对象. 可以简单的通过
find() 来查询, 他返回一个任意结构的集合. 如果实现特定的查询稍后讲解.
实现上面同样的查询, 然后通过while 来输出:
> var cursor = db.things.find();
> while (cursor.hasNext()) printjson(cursor.next());
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x": 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x": 4, "j" : 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x": 4, "j" : 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x": 4, "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x": 4, "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x": 4, "j" : 5 }
上面的例子显示了游标风格的迭代输出. hasNext() 函数告诉我们是否还有数据, 如果有则
可以调用next() 函数.
当我们使用的是JavaScript shell, 可以用到 JS 的特性, forEach 就可以输出游标了. 下面的例
子就是使用forEach() 来循环输出: forEach() 必须定义一个函数供每个游标元素调用.
> db.things.find().forEach(printjson);
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x": 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x": 4, "j" : 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x": 4, "j" : 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x": 4, "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x": 4, "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x": 4, "j" : 5 }
在MongoDB shell 里, 我们也可以把游标当作数组来用:
> var cursor = db.things.find();
> printjson(cursor[4]);
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x": 4, "j" : 3 }
使用游标时候请注意占用内存的问题, 特别是很大的游标对象, 有可能会内存溢出. 所以应
该用迭代的方式来输出. 下面的示例则是把游标转换成真实的数组类型:
> var arr = db.things.find().toArray();
> arr[5];
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x": 4, "j" : 4 }
请注意这些特性只是在 MongoDB shell 里使用, 而不是所有的其他应用程序驱动都支持.
MongoDB 游标对象不是没有快照,如果有其他用户在集合里第一次或者最后一次调用
next(), 你可能得不到游标里的数据. 所以要明确的锁定你要查询的游标.
4.4 条件查询
SELECT * FROM things WHERE name="mongo"
> db.things.find({name:"mongo"}).forEach(printjson);
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
SELECT * FROM things WHERE x=4
> db.things.find({x:4}).forEach(printjson);
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x": 4, "j" : 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x": 4, "j" : 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x": 4, "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x": 4, "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x": 4, "j" : 5 }
SELECT j FROM things WHERE x=4
> db.things.find({x:4}, {j:true}).forEach(printjson);
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "j": 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "j": 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "j": 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "j": 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "j": 5 }
4.5 findOne()语法
> printjson(db.things.findOne({name:"mongo"}));
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
4.6 通过 limit 限制结果集数量
> db.things.find().limit(3);
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x": 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x": 4, "j" : 1 }
4.7 修改记录
将 name 是 mongo 的记录的 name 修改为 mongo_new
>db.things.update({name:"mongo"},{$set:{name:"mongo_new"}});
我们来查询一下是否改过来了
> db.things.find();
{ "_id" : ObjectId("4faa9e7dedd27e6d86d86371"), "x": 3 }
{ "_id" : ObjectId("4faa9e7bedd27e6d86d86370"), "name" : "mongo_new" }
4.8 删除记录
将用户 name 是 mongo_new 的记录从集合 things 中删除
> db.things.remove({name:"mongo_new"});
> db.things.find();
{ "_id" : ObjectId("4faa9e7dedd27e6d86d86371"), "x": 3 }
经验证,该记录确实被删除了
5 附加
MongoDB 在 bin 目录下提供了一系列有用的工具,这些工具提供了 MongoDB 在运维管理上
的方便。
●bsondump: 将 bson 格式的文件转储为 json 格式的数据
●mongo: 客户端命令行工具,其实也是一个 js 解释器,支持 js 语法
●mongod: 数据库服务端,每个实例启动一个进程,可以 fork 为后台运行
●mongodump/ mongorestore: 数据库备份和恢复工具
●mongoexport/ mongoimport: 数据导出和导入工具
●mongofiles: GridFS 管理工具,可实现二制文件的存取
●mongos: 分片路由,如果使用了 sharding 功能,则应用程序连接的是 mongos 而不是
mongod
●mongosniff: 这一工具的作用类似于 tcpdump,不同的是他只监控 MongoDB 相关的包请
求,并且是以指定的可读性的形式输出
●mongostat: 实时性能监控工具
客户端 GUI 工具
主页:http://www.mongovue.com/
一个桌面程序,提供了对 MongoDB 数据库的基本操作,如查看、查询、更新、删除等,简
单易用,但是功能还比较弱,以后发展应该不错。
下载地址:
MongoDB高级查询日后补充。。。
参考文档:MongoDB权威指南.pdf