假设mongoDB 安装在 /usr/local/mongod
一.MongoDB shell 使用
使用MongoDB shell 的前提是,先启动 mongodb(有点废话).
>./mongod
mongoDB shell 其实就是一个javascript 解释器, 所以可以
像在firebug里面的控制台一样执行Javascirpt 程序, 当然可以使用 Javascript
的标准库.
开始前必须了解核心数据结构. 文档 和 集合
文档:相对于关系数据库就是一条记录,表中的一行. 是mongodb 的基本单元.
集合: 可以看作是关系数据库中的表.
如果重javasript 语言 来看 文档就是一个Object. 集合就是很多文档组合的大Object.
>./mongo
2. 使用内置帮助文档
>help
3. 查看mongodb 中有哪些数据库:
>show dbs
4. 使用数据库, 和mysql 一样使用use 指令:
比如使用 blog 数据库
>use blog
(你会发现使用不存在的数据库也是可以的, 但是使用 show dbs 查看数据库列表时,
blog 数据库并没有出现在列表里, 只有向这个书库里添加了数据后才会创建.)
5.使用 db 指令查看当前使用的数据库.
>db
blog
(这里的db 就是一个变量了(其实就数据库的一个实例, 是一个 object了),
就像浏览器里面的控制台一样, 输入变量会显示值, mongoDB shell 既然是个
javascript 解释器, 那么变量也就和javacript 变量一样操作了).
二: 数据类型:
文档包含的基本数据类型:
null
布尔 true/false
整数: 32位 和 64位
64位浮点数
字符串
符号
对象id
日期
正则表达式
代码:
二进制数据
最大值
最小值
undifined
数组
内嵌文档.
三.数据库的操作CRUD, 创建, 读取, 更新, 删除
创建, 更新, 和删除都是瞬间完成, 不需要等待数据库响应.
1. 使用 insert 指令添加文档到集合(还记得javascritp 的对象使用吗, 没错一切就是那么简单).
>userinfo = {"name":"Lee"}
>db.user.insert(userinfo)
注意: 如果插入多条记录, 批量插入会更快, 但是请注意MongoDB 对消息长度和文档大小的限制(每个MongoDB版本估计不一样请查看手册);
2.集合有两个查看方法: find() 和 findOne(), 可以接受参数.具体可以使用一个章节来说明.
和其他关系数据库数据库一样, 相当于selete.
find/findOne(query, key)
query 条件
key 要返回的键
1) 使用$条件查询,
$lt <
$lte <=
$gt >
$gte >=
$ne !=
$in
$nin
$or
这三个都是多值匹配,所以对应的是个数组.
$not 非 一般和其他的条件联合查询
$exists 是否存在
使用正则表达式匹配.
$all
$size
$slice
使用" . " 来查询内嵌文档(所以存储文档时,不应出现点号, 最好是全局替换点号).
$elemMath 模糊匹配(限定条件分组)
2)使用$where子句, 应当避免使用$where子句(比常规查询慢很多, 每个文档要从BSON转换成js对象,然后同$where 表达式运行,相当于定义了一个 javascript 函数通过这个$where 函数来过滤数据).
3)数据库游标(用来放回find的执行结果).
方法: hasNext() 是否存在下一个值, next()获取下一个值.
4)限制函数(注意这些选项一定要查询被派发到服务器之前添加):
limit() 限制,指定数目上限值.
skip() 忽略集合的前几条文档(忽略够多会导致导致性能问题,因尽量避免).
sort() 排序
5)关于分页问题;
6)关于随机取文档问题;
7) 高级查询选项:
$maxscan 最多要查找的文档数
$min 查询开始条件
$max 查询结束条件
$hint 指定使用哪个索引进行查询
$explain 获取查询执行细节
$snapshot 确保查询的结果是在查询执行那一刻的一致快照.
3.使用update 方法更新数据, 最少接受两个参数, update("条件", "新数据"),
update(query, object, upsert, multi)
>userinfo.name = "Tom";
>db.user.update({"name":"Lee"}, userinfo);
注意: update 默认不属于原子操作, 当第三个参数 upsert 赋值为 true 时为原子操作, 如果条件在集合中没有配置到,会将条件作为初始数据插入到集合中,
并更新数据.
第四个参数 multi 设置为true时, 表示可以对多个文档进行更新, 默认为false时,只更新一个(建议使用update 方法时四个参数都写上).
使用更新修改器(都是原子操作):
$inc 数字递增/减
$set 增加/修改
$unset 删除
对数组操作
$push
$ne
$addToSet
$each
$pop 从头部删除-1, 从尾部删除1.
$pull 将匹配到的删除.
$ 定位符. update 条件表达式,对应在集合中的的位置.
4.remove 永久删除数据库中的文档, 没有参数时,删除整个集合中的文档.
remove("条件")
>db.user.remove({"name":"Tom"})
注意: 当集合中有数据比较多大情况下,要清除集合时
db.集合.remove() 明显比
db.drop_collection("集合") 慢,
remove 会保留集合 和 索引,删除数据后还要重建索引.而drop_collection() 是直接删除集合,集合和索引都不保留.
明显是先使用 drop_collection 删除集合再创建一个同名的集合. 如果摸个键只是用来表示某种状态就没有必要给它创建
索引(和众多关系数据库一样).
执行指定的命令
1. 如果获取上次操作错误/更新条数等:
db.runCommand({getLastError:1});
2. findAndModify 命令, 顾名思义, 先查找再修改.
使用:
db.runCommand( {
"findAndModify":"query",
"action": {...}
...
});
多个action组合, 可以是:
query, sort, update, remove, new
update 和 remove 必须出现一个,不能同时出现.
这个命令一次只能处理一个文档, 不能处理upsert.
相对普通的更新,要慢一些.
四.索引
创建和修改索引:
使用:ensureIndex() 方法
比如对user集合创建一个以'username'作为
普通索引:
db.user.ensureIndex({"username":1});对内嵌文档创建索引:db.blog.ensureIndex({"commnents.date":1});
ensureIndex() 第一个参数来指定要创建的索引, 第二个参数可以对索引进行命名:db.blog.ensureIndex({"commnents.date":1}, {"name":'cmt_date'});还可以指定索引类型:db.user.ensureIndex({"username":1}, {'unique': true}); // 唯一索引//复合索引(详细可以查看MONGODB的GirdFS那个章节).
值 1 或 -1 表示索引的方向, 如果索引就只有一个键(单键索引),方向就无关紧要. 就如: 从A-Z ,还是从 Z-A.如果是多键索引就值得考虑方向.举例: 如果user 集合中对 键 username 和 age 创建一个索引:db.user.ensureIndex({"username":1, "age": -1});对username按字母顺序, 年龄age 按照降序来排列, 那username相同的就是按照age降序排列.创建索引的缺点就是在插入,更新和删除时都会产生额外的开销(需要维护这些索引).要合理的创建索引(默认最大索引数目64个).
创建索引前,先回答一下问题:1)是什么样的查询, 哪些键需要索引?2)每个键的索引方向是怎么样的?3)如果应对扩展(在索引中键的先后顺序, 会导致数据使用内存的大小, 尽快能数据多的保留咋内存中, 提高内存的利用率)?
注意:1) 对要排序的键创建索引(对没有索引的键进行排序的话, mongoDB会把数据提取到内存中进行排序, 如果数据太大, 可能会导致内存耗光).2)消除重复. 如果对已经有数据的集合创建唯一索引, 集合中可能有些值是重复的, 如果发生这种情况创建索引会失败. 如果需要把重复的删除掉,可以使用"dropDups" 比如:db.people.ensureIndex({"username":1}, {"unique":true, "dropDups":true}). 对于重要的数据来说话,这个语句很危险. 建议用脚本做批量处理.3) 集合名称长度不能超过121字节(每个数据库的system.namespaces 集合中,命名空间长度是127字节, 默认的情况下命名空间需要 .$_id_ 刚好就是6个字节,如果名称超过了121字节,在命名空间集合中, 集合名称+索引名称超过了 127字节).
删除索引
使用 dropIndex() / dropIndexes;
>db.runCommand({"dropIndexes": "foo", "index" : "alphabet"});
工具的使用:
1)explain() 类似mysql 的explain使用用列:db.user.find().explain();可以发现是游标对explain 调用, 然后返回查找查询细节文档(非游标文档).2)hint() 强制使用某个索引.
索引管理:
索引集合system.indexes 集合system.namespaces 集合
特殊索引: 2d - 地理空间索引(以后详细介绍)
五.聚合工具
- count
db.foo.count();
db.foo.count({"x":1});
- distinct
db.runCommand( { "distinct" : "people", "key" : "age"} );
必须字节集合名称和要查询的键
- group
db.runCommand( {"group" : {
"ns" : "集合名称",
"key" : "键",
"initial" : "{初始化值}",
"$reduce" : function (cur, pre) {
//操作函数, 有两个参数, cur 当前文档, pre 累加器文档
},
"condition" : {条件},
"$finalize" : function(pre){
//完成器
},
"$keyf":function(){
//处理键
},
}} );
没一组都有一个独立的累加器.
- MapReduce(独立学习)
六.安装PHP mongo 扩展(mongoDB PHP 驱动程序)
#tar -zxvf mongo-1.4.3.tgz
#cd mongo-1.4.3
#/usr/local/php-5.3.21/bin/phpize
#./configure --with-php-config=/usr/local/php-5.3.21/etc/php.ini
#make && make install
添加mongo扩展
#vim /usr/local/php-5.3.21/etc/php.ini
重启PHP
#service php-fpm restart
用phpinfo 函数查看是否安装成功.