mongo官网:http://www.mongodb.org/
工作中使用到Mongo,但是没有系统的学习研究过Mongo,仅对工作过程中,在Mongo的使用过程中的一些知识点做一下记录,并随时补充,达到总结备忘的目的。
本篇主要记录安装启动、聚合和查询。
下载mongo,解压后,拷贝到一个位置,比如:/data/mongo3.0.1。配置一个配置文件mongod.conf,内容如下:
# 数据库文件保存位置 dbpath=/data/mongo3.0.1/db # 日志文件存放位置 logpath=/data/mongo3.0.1/log/mongod.log # 以追加方式写入日志 logappend=true # 是否已守护进程方式运行(后台运行) fork=true # 设置端口(默认27017) #port=27017 # Enables periodic logging of CPU utilization and I/O wait # 启用定期记录CPU利用率和 I/O 等待 #cpu=true #磁盘剩余空间不足4G,用这个参数 smallfiles=true
设置一个启动命令,vim /data/mongo3.0.1/startmongo.sh,内容如下:
/data/mongo3.0.1/bin/mongod -f /data/mongo3.0.1/mongod.conf
然后把这个命令,加入启动列表,即可:vim /etc/rc.local
为了更方便的使用mongo命令,可以把mongo加入环境变量,vim /etc/profile,增加一行:
export MONGO_HOME=/data/mongo3.0.1 export PATH=$PATH:$MONGO_HOME/bin
db.view_view.count()
db.view_view.count({_id:"521842"})
db.view_view.find().count()
db.view_view.find({_id:"521842"}).count()
db.view_view.distinct("_id")
db.view_view.distinct("view") view是个数组,会把每个数组的元素都distinct一下
db.invoke_stat.group({ key:{ip:true}, cond:{ date:{$gte:ISODate("2014-07-09 16:00:00"),$lt:ISODate("2014-07-10 16:00:00")} }, reduce:function(curr,result){ result.count += curr.times; }, initial:{count:0}, finalize:function(result) {result.count = '$' + result.count} }); db.view_view.group({ keyf:function(doc){return {view_num:doc.view.length}}, reduce:function(curr,result){ result.count += 1; result.id = curr._id; }, initial:{count:0} });
key/keyf:要按照进行分组的列,key是直接选取表中的列,kef是一个函数,对列进行一些处理,函数结果要返回一个对象,比如{view_num:doc.view.length},doc.view.length,是表中的数组列view的长度。
cond:是要过滤的查询条件
reduce:处理函数
initial:返回列的初始值
finalize:对reduce的结果进行进一步处理,比如格式化
db.invoke_stat.mapReduce( function(){ var key = this.ip; emit(key,{r_times:this.times}) }, function(key,emits){ total=0; for(var k in emits) { total+=emits[k].r_times; } return {r_times:total} }, {out:'mr'} )
mapReduce的原型为:function (map, reduce, optionsOrOutString),下面具体介绍一下函数的三个参数:
map函数,它会遍历集合中的每一个文档,this表示文档,它使用emit方法将文档按键分组,并返回需要统计的数据;
reduce函数,它将收集数据并统计,两个参数分别为map函数返回的key值和数据数组;
optionsOrOutString参数为一个对象,定义了一些额外工作,比如上面的列子中使用out参数将统计结果放入到mr集合中,集合不存在则创建,存在了则覆盖。
参数optionsOrOutString对象除了out键以外还有其它一些键:
finalize函数,同group的finalize完成器一样,可以对reduce的结果做一些处理;
query文档,在map函数前对文档过滤;
sort文档,在map函数前对文档排序,必须先对排序的字段建立索引;
limit整数,在map函数前设定文档数量;
scope文档,js函数中用到的变量,客户端可以通过scope传递一些值;
jsMode布尔,指定了map和reduce函数间传递的对象使用BSON格式还是javascript对象,默认值false,表示采用BSON格式,优点是中间的BSON数据会被存在硬盘上,所以传递的数据量可以很大,但会影响性能;采用javascript对象,性能较高,但只能传递50万个不同的key值;
verbos布尔,默认true,显示详细的时间统计信息。
以上可以看出MapReduce的强大,可以很轻松的实现不同的统计功能。
mongo查询语法:
db.access_logs_140701.find({jxTime:{$gt:1407011300,$lt:1407011400},"curl.sku":"99978033"}).sort({jxTime:-1}).skip(1).limit(100)
db.access_logs_201501.find({jxTime:{$gt:1501120000,$lt:1501121750},"curl.type":{$nin:[40,41,42,43]}}).size()
db.invoke_stat.find({date:{$gte:ISODate("2014-07-09 10:00:00"),$lt:ISODate("2014-07-09 11:00:00")}})
db.view_view.find({view:{$size:10}}) 查询数组长度为10的,当前Mongo不直接支持数据长度范围查询,比如查询数据长度<10的,只能MapReduce编程实现
mongodump/mongorestore:既可以对数据库备份还原,也可以对表备份还原,完成后在目录下有两个文件.json(描述文件)和.bson(数据文件),命令演示如下:
./mongodump -d recommend -c access_logs_121110 -o /data/mongobackup/recommend/access_logs_121110
把recommend库的access_logs_121110表备份到一个目录下
./mongorestore -d recommend -c access_logs_121110 --directoryperdb /data/mongobackup/recommend/access_logs_121110/recommend/access_logs_121110.bson
还原数据到表中
命令在各个版本中是稍有差别的,比如在3.0中,--directoryperdb参数就没有了,变成了dir,所以还是要经常看--help来研究使用办法。
mongorestore -d sia_db -c sia_collection --drop --dir=/root/sia_db/sia_collection.bson
mongodump数据备份,1G数据大约花费30秒;mongorestore数据还原,1G数据大约花费5-6分钟。
mongoimport/mongoexport可以对表执行数据导入导出,mongoexport数据导出时,不会导出索引,mongoimport数据导入时,对于自动的_id会重新赋值,这个要注意下。
mongodb删除集合后磁盘空间不释放,只有用db.repairDatabase()去修复才能释放。如果是删除库,则会立马释放空间,硬盘上相应库的数据文件会被删除。
但是在修复的过程中如果出现了非正常的mongodb的挂掉,再次启动时启动不了的,需要先修复才可以,可以利用./mongod --repair --dbpath=/data/mongo/ 。
如果你是把数据库单独的放在一个文件夹中指定dbpath时就指向要修复的数据库就可以,修复可能要花费很长的时间,在使用db.repairDatabase()去修复时一定要停掉读写,并且mongodb要有备机才可以,不然千万不要随便使用db.repairDatabase()来修复数据库。
use test:创建数据库,如果之后不做任何操作退出,则数据库会被自动删除
show users:查看用户
db.addUser("username","password"):增加用户