mongodb支持google提出的mapreduce并行编程,通过启动分片和水平扩展、读写分离,与关系数据库比较:table –> collection; row –>doucument/object(BSON)。
mongodb进程
mongod进程:负责整个mongodb中最核心的内容,负责数据库的创建, 删除等,运行在服务器上进行监听。
1234567mongod --config /home/honeycc/properties.conf# properties.conf# dbpath = /home/honeycc/db/data# logpath = /home/honeycc/logs/log.log# journal = true 启动数据库实例的日志功能,数据库当宕机后重启恢复# port = 27017# auth = true 启动数据库实例的权限控制功能mongo进程:交互式shell界面
12mongo --port 27017 -u root -p root-autheticationDatabase gps_dbmongodump备份、mongoexport、mongoimport、mongos分片、mongofiles分布式文件存储系统接口、mongostat状态、mongotop性能跟踪
12345678mongodump --port 27017 --db gps_db--out /home/honeycc/backmongoexport --port 27017 --db gps_db--collection gps_data --out /home/honeycc/gps_data.jsonmongoinport --port 27017 --db gps_db--collection gps_data --file /home/honeycc/gps_data.json
mongodb 数据库操作
查询选择器
123456789101112131415161718db.gps_data.find().pretty()# 格式化输出db.gps_data.find({id:9,"province":"Zhejiang"})# 精确查找db.gps_data.find({"GPSTIME":{"<":new Date("2016-12-10")})# 比较操作符"$gt" 、"$gte"、 "$lt"、 "$lte"、"$ne"(分别对应">"、 ">=" 、"<" 、"<="、"="),组合起来进行范围的查找db.gps_data.find({"GPSTIME":{"$in":[null],$exists:true}})# 返回gpstime为null值的文档,如果$exists:false返回gpstime不为null的所有字段#$in:[] ; $nin:[].单独使用$nin $ne会进行全表扫描,应与其他选择器配合使用db.gps_data.find({$and:[{},{}]})# $or:[{},{}] $and:[{},{}]db.gps_data.find("driver.message.age":20)# 多层结构查询投射
123456789db.gps_data.find({"GPSTIME":{"<":new Date("2016-12-10")},{_id:0,GPSTIME:1,CODE:1,driver.message.phone:1,GPSTIME:{"$slice":-1}})# db.gps_data.find({},{})# 第一个{}内为查询选择器;第二个{}内为对前面返回的结构集进一步过滤条件,投射项,$slice:-1返回数组最后一条数据db.gps_data.find({}).sort({id:-1})# 排序效率低下,尽量确保排序的在索引上db.gps_data.find({}).skip(10).limit(5).sort({id:-1})# 先排序,然后跳过10条,获取5条,尽量少用skip,效率低数组操作
12345678db.gps_data.find({driver.message.phone:[110,112]})# 数组精确匹配db.gps_data.find({driver.message.phone:112})# 数组包含匹配db.gps_data.find({driver.message.phone.1:112})# 数组位置匹配,第二个电话为112的增删改
123456789101112131415db.gps_data.insert({}) # _id 要唯一db.gps_data.update(query,update,<upsert>,<multi>)db.gps_data.update({CODE:"浙B26827"},{$set : { GPSTIME:new Date() },$inc:{driver.message.phone:100}})# 第一个文档 更改车牌为浙B26827的,$set 把GPSTIME更改为当前时间,$inc 新增属性db.gps_data.update({CODE:"浙B26827"},{CODE:"浙B26821"})# 第一个文档 把其他属性都擦除掉了db.gps_data.update({CODE:"浙B26827"},{$set:{GPSTIME:new Date() },$inc:{driver.message.phone:100}},{upsert:true} ,{multi:true})# {multi:true} 所有文档 {upsert:true} 找不到则插入db.gps_data.remove(<query>,<justOne>)db.gps_data.remove({CODE:"浙B26827"},1)# 删除全部、limt 1 删除一个索引:提高数据获取的性能
在linux文件系统中,磁盘抽象为引导块 超级块 索引节点表 数据块
流程:索引节点表保存了所有文件或者目录对应的inode节点,通过文件名或目录找到对应的inode节点,通过inode节点定位到文件数据在文件系统中的逻辑块号,最后根据磁盘驱动程序将逻辑块号映射到磁盘具体的块号。
数据库上保存记录的机制是建立在文件系统上的,索引也是以文件的形式存储在磁盘上,运用最多的索引结构是B树。
Mongodb索引:B+树
db.gps_data.ensureIndex({})创建索引
db.gps_data.dropIndex(“GPSTIME_1_CODE_1 “)- 单字段索引 _id,唯一索引 {unique:true}: db.system.indexes.find()
- 符合索引 db.gps_data.ensureIndex({GPSTIME:1,CODE:1})
- 数组的多键索引 对一个值为数组类型的字段创建索引,则默认会对数组中的每一个元素创建索引。
聚集分析:聚集操作是对数据进行分析的有效手段。mongodb主要提供了三种对数据进行分析的计算方式:管道模式聚集分析、Mapreduce聚集分析、简单函数和命令的聚集分析
管道模式:类unix上的管道命令 grep 层层过滤
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869db.gps_data.aggregate([{$match:{}},{$group:{}}])'''常用管道操作符$match: 过滤文档,值传递匹配文档到管道中的下一步骤$limit: 限制管道中文档的数量$skip: 跳过指定数量文档$sort: 多所有文档进行排序$group: 对所有文档进行分组然后计算聚集结果$out: 将管道中的文档输出到一个具体集合中与$group操作一起使用的计算聚集值的操作符$first、$last、$max、$min、$avg、$sum'''# SQL语句与mongodb聚集操作语句比较# select count(*) as count from gps_datadb.gps_data.aggregate([{$group:{_id:null,count:{$sum:1}}}])# select sum(num) as total from gps_datadb.gps_data.aggregate([{$group:{_id:null,total:{$sum:"$num"}}}])# select driver_id,sum(num) as total from gps_data group by driver_iddb.gps_data.aggregate([{$group:{_id:"$driver_id",total:{$sum:"$num"}}}])# select driver_id,gpsdate,sum(num) as total from gps_data group by driver_iddb.gps_data.aggregate([{$group:{_id:{driver_id:"$driver_id",gpsdate:"gpsdate"},total:{$sum:"$num"}}}])# select driver_id, count(*) from gps_data group by driver_id having count(*) > 1db.gps_data.aggregate([{$group:{_id:"$driver_id",count:{$sum:1}}},{$match:{count :{$gt:1}}}])```2. Mapreduce模式聚集:用Mongodb做分布式存储,然后再用Mapreduce来做分析```shelldb.gps_data.mapReduce(# map 函数function(){emit(this.driver_id,this.num);},# reduce 函数funtion(key,values){return Array.sum(values)},{query:{ CODE:"浙B25681"}, # 查询条件outresult:"driver_car_total" # 输出结果到集合上})<---->select sum(num) as value, driver_id as _idfrom gps_datawhere CODE="浙B25681"group by driver_id将结果输出到 driver_car_total集合上db.driver_cat_total.find(){"_id":1,"value":2}简单聚集函数
12345678910111213141516# 1、distinct# db.collection.distinct(key,<query>)# 2、count# db.collection.find(<query>).count()# 3、group,结果集不能大于16M,不能在分片集群上进行操作且不能处理超过10000个唯一键值# db.collection.group({key:..., initial:...,reduce:...[,cond:...]})# eg:db.gps_data.group({key:{_id:1},cond:{_id:{$lt:3}},reduce:function(cur,result){result.count += cur.count;}initial: {count:0}})# 统计_id小于3,按照_id分组求value值的和
JAVA操作Mongodb
Maven pom.xml配置驱动
Mongodb工具类
使用mongodb插件 mongodb plugin
|
|
mongodb api文档教程
mongodb plugin 插件使用教程
总结
第一次接触nosql数据库,还有很多需要去学习东西,在java上去开发还不是那么流畅,插件的使用还不是很顺畅,但是运用起来还是感觉很舒服。
在数据量打的情况下,只做数据处理的前提,最好是先在数据库去将数据处理好,再用java mongodb api 去调用数据库,获取处理好的数据,避免的在逻辑层去处理大量的数据,这样的性能效率才能高