一、创建数据库



use foobar



二、创建集合



db.persons.insert({name:"zhaomin",age:23})



三、查找

find()



findOne()



四、修改

update({name:"zhaomin"},{ $set:{age:18}}) #不会影响其他属性列 ,主键冲突会报错



update({name:"zhaomin"},{ $set:{age:18}},true) #第三个参数为true 则执行insertOrUpdate操作,查询出则更新,没查出则插入,或者



findOne();



update(p,{name:"zhaomin1"}) #会删除其他的属性列



五、删除

remove({age:1}) #删除满足条件的第一条 只删除数据 不删除索引



#删除集合



drop();



#删除数据库



dropDatabase();



六、查看集合

show collections



查看数据库

show dbs



七、插入数据

insert() #不允许键值重复



save() #若键值重复,可改为插入操作



八、批量更新

db.persons.update({name:"zhaomin"},{$set:{name:"zhanmin11"}},false,true);



  批量操作需要和选择器同时使用,第一个false表示不执行 insertOrUpdate操作,第二个true表示执行批量



九、更新器使用 $set : 指定一个键值对,若存在就进行修改,不存在则添加



   $inc :只使用于数字类型,可以为指定键值对的数字类型进行加减操作:

db.persons.update({name:"zhangsan"},{$inc:{age:2}})



   $unset : 删除指定的键

db.persons.update({name:"zhangsan"},{$unset:{age:1}})



   $push : 数组键操作:1、如果存在指定的数组,则为其添加值;2、如果不存在指定的数组,则创建数组键,并添加值;3、如果指定的键不为数组类型,则报错;



   $pushAll : 批量想数组键插入值

db.persons.update({name:"zhangsan"},{$pushAll:{classes:["English","Math","Chinese"]}});



   $addToSet : 当指定的数组中有这个值时,不插入,反之插入

db.persons.update({name:"zhangsan"},{$addToSet:{classes:"English"}}); #则不会添加到数组里



   $pop:删除指定数组的值,当value=1 删除最后一个值,当value=-1 删除第一个值

db.persons.update({name:"zhangsan"},{$pop:{classes:1}}) #删除了最后一个值



   $pull : 删除指定数组指定的值

db.persons.update({name:"zhangsan"},{$pull:{classes:"Chinese"}}) #$pullAll批量删除指定数组指定的值 指定一定是数组,否则会报错



db.persons.update({name:"zhangsan"},{$pull:{classes:["Chinese"]}}) #若数组中有多个Chinese,则全删除



   $ : 修改指定数组时,若数组有多个对象,但只想修改其中一些,则需要定位器:

db.persons.update({"classes.type":"AA"},{$set:{"classes.$.sex":"male"}})



   $addToSet$each结合完成批量数组更新操作

db.persons.update({name:"zhangsan"},{$set:{classes:{$each:["chinese","art"]}}})



十、 runCommand函数和 findAndModify函数

runCommand({



  findAndModify:"persons",



  query:{查询器},



  sort:{排序},



  update:{修改器},



  new:true 是否返回修改后的数据



});



  runCommand函数可执行mongdb中的特殊函数



  findAndModify就是特殊函数之一,用于返回执行返回update或remove后的文档



  例如:

runCommand({ 
     
 
     

         findAndModify:"persons", 
     
 
     

         query:{name:"zhangsan"}, 
     
 
     

         update:{$set:{name:"lisi"}}, 
     
 
     

         new:true 
     
 
     

       }) 
     
 
     

       ps.value



十一、查询详讲

db.persons.find({},{_id:0,name:1})



  第一个空括号表示查询全部数据,第二个括号中值为0表示不返回,值为1表示返回,默认情况下若不指定主键,主键总是会被返回;



  db.persons.find({条件},{指定键});



  比较操作符: $lt: < $lte: <= $gt: > $gte: >= $ne: !=



  1、查询条件

db.persons.find({age:{$gte:25,$lte:27}},{_id:0,name:1,age:1}) #查询年龄大于等于25小于等于27的人 
db.persons.find({country:{$ne:"韩国"}},{_id:0,name:1,country:1}) #查询出所有国籍不是韩国的人的数学成绩



  2、包含与不包含(仅针对于数组)



     $in$nin

db.persons.find({country:{$in:["China","USA"]}},{_id:0,name:1:country:1}) #查询国籍是中国或美国的学生信息



  3、 $or查询



db.persons.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]},{_id:0,name:1,c:1,e:1}) #查询语文成绩大于85或者英语大于90的学生信息
db.persons.update({country:"China"},{$set:{sex:"m"}},false,true) #把中国国籍的学生上增加新的键sex 
db.persons.find({sex:{$in:[null]}},{_id:0,name:1,sex:1}) #查询出sex为null的人



  4、正则表达式

db.persons.find({name:/li/i},{_id:0,name:1}) #查询出名字中存在”li”的学生的信息



  5、 $not的使用



     $not$nin的区别是$not可以用在任何地方儿$nin是用到集合上的

db.persons.find({name:{$not:/li/i}},{_id:0,name:1}) #查询出名字中不存在”li”的学生的信息



  6、 $all与index的使用

db.persons.find({books:{$all:["JS","MONGODB"]}},{_id:0,name:1}) #查询喜欢看MONGOD和JS的学生
db.persons.find({"books.1":"JAVA"},{_id:0,name:1,books:1}) #查询第二本书是JAVA的学习信息



  7、 $size的使用,不能与比较查询符同时使用

db.persons.find({books:{$size:4}},{_id:0,name:1}) #查询出喜欢的书籍数量是4本的学生



  8、查询出喜欢的书籍数量大于4本的学生本的学生



  1)增加size键

db.persons.update({},{$set:{size:4}},false,true)



  2)添加书籍,同时更新size

db.persons.update({name:"jim"},{$push:{books:"ORACL"},$inc:{size:1}})



  3)查询大于3本的

db.persons.find({size:{$gt:4}},{_id:0,name:1,size:1})



  9、 $slice操作符返回文档中指定数组的内部值

db.persons.find({name:"jim"},{_id:0,name:1,books:{$slice:[1,3]}}) #查询出Jim书架中第2~4本书
db.persons.find({name:"jim"},{_id:0,name:1,books:{$slice:-1}}) #查询出最后一本书



  10、文档查询



    查询出在K上过学且成绩为A的学生



  1)绝对查询,顺序和键个数要完全符合

db.persons.find({school:{school:"K","score":"A"}},{_id:0,name:1})



  2)对象方式,但是会出错,多个条件可能会去多个对象查询

db.persons.find({"school.school":"K","school.score":"A"},{_id:0,name:1})



  3)正确做法单条条件组查询$elemMatch

find({school:{ 
     $elemMatch:{school:"K",score:"A"}},{_id:0,name:1}) 
    
 
    
find({age:{ 
     $gt:22},books:"C++",school:"K"},{_id:0,name:1,age:1,books:1,school:1})


  11、分页与排序



  1) limit返回指定条数 查询出persons文档中前5条数据:

db.persons.find({},{_id:0,name:1}).limit(5)



  2)指定数据跨度 查询出persons文档中第3条数据后的5条数据

db.persons.find({},{_id:0,name:1}).limit(5).skip(3)



  3) sort排序 1为正序,-1为倒序 

db.persons.find({},{_id:0,name:1,age:1}).limit(5).skip(3).sort({age:1})



    注意:mongodb的key可以存不同类型的数据排序就也有优先级



    最小值->null->数字->字符串->对象/文档->数组->二进制->对象ID->布尔->日期->时间戳->正则->最大值



  12、游标



    利用游标遍历查询数据

var persons = db.persons. 
     find(); 
    
 
    
hasNext()){ 
    
 
    
next(); 
    
 
    
print(obj.name) 
    
 
    

      }



  游标几个销毁条件



  1).客户端发来信息叫他销毁



  2).游标迭代完毕



  3).默认游标超过10分钟没用也会别清除



  13、查询快照



    快照后就会针对不变的集合进行游标运动了,看看使用方法.

db.persons.find({$query:{name:”Jim”},$snapshot:true}) #用快照则需要用高级查询



  高级查询选项



  1) $query



  2) $orderby



  3) $maxsan:integer 最多扫描的文档数



  4) $min:doc查询开始



  5) $max:doc查询结束



  6) $hint:doc使用哪个索引



  7) $explain:boolean统计



  8) $snapshot:boolean 一致快照



十二、索引



  1.创建索引

db.books.ensureIndex{{number:1}}



  创建索引同时指定索引的名字

db.books.ensureIndex({number:1},{name:"book_"})



  2.索引使用需要注意的地方



  1)创建索引的时候注意1是正序创建索引-1是倒序创建索引



  2)索引的创建在提高查询性能的同事会影响插入的性能 对于经常查询少插入的文档可以考虑用索引



  3)符合索引要注意索引的先后顺序



  4)每个键全建立索引不一定就能提高性能呢 索引不是万能的



  5)在做排序工作的时候如果是超大数据量也可以考虑加上索引 用来提高排序的性能



  3.唯一索引



    解决文档books不能插入重复的数值

db.books.ensureIndex({name:-1},{unique:true}) #则插入相同的name值会报错



  4.踢出重复值



    如果建议唯一索引之前已经有重复数值如何处理



db.books.ensureIndex({name:1},{name:"book_",unique:true,dropDups:true}) #踢出重复数值



  5.后台执行创建索引



    为了解决创建索引锁表的问题,在不影响查询功能,可以在后台运行

db.books.ensureIndex({name:1},{background:true})



  6.强制查询已经建立好的索引

db.books.find({name:"323book"}).hint({name:1}) #后一个name为索引名,正序倒序依据建立索引的规则,否则会报错



  7.在shell查看数据库已经建立的索引

indexes. find()



namespaces. find()



  8.查询索引信息和查询状态信息

db.books.find({name:"123book"}).explain()



  9.批量和精确删除索引

runCommand({dropIndexes : "books" , index:"name_-1"})



runCommand({dropIndexes : "books" , index:"*"})



十三、二维索引



  建立二维索引

db.map.ensureIndex({gis:"2d"},{min:-1,max:201}) #默认会建一个[-108,108]的范围



  1.查询点(70,180)最近的3个点

db.map.find({gis:{$near:[70,180]}},{_id:0,gis:1}).limit(3)



  2.查询以点(50,50)和点(190,190)为对角线的正方形中的所有的点

db.map.find({gis:{$within:{$box:[[50,50],[190,190]]}}},{_id:0,gis:1})



  3.查询出以圆心为(56,80)半径为50规则下的圆心面积中的点

db.map.find({gis:{$with:{$center:[[56,80],50]}}},{_id:0,gis:1})



十四、Count+Distinct+Group



  1. count 查询结果条数

db.persons.find({country:"USA"}).count()



  2. Distinct 去重



  请查询出persons中一共有多少个国家分别是什么

db.runCommand({distinct:"persons",key:"country"}).values #key表示去重的键



  3. group分组

runCommand({ group:{



  ns:"集合的名字",



  key:"分组键对象",



  initial:"初始化累加器",



  $reduce:"分解器",



  condition:"条件",



  finalize:"组完成器"



}})



  分组首先会按照key进行分组,每组的 每一个文档全要执行$reduce的方法,他接收2个参数一个是组内本条记录,一个是累加器数据.



  请查出persons中每个国家学生数学成绩最好的学生信息(必须在90以上)

runCommand({ 
    
 
    
group:{ 
    
 
    

        ns:"persons", 
    
 
    

        key:{"country":true}, 
    
 
    

        initial:{m:0}, 
    
 
    
reduce:function(doc,prev){ 
    
 
    

          if(doc.m>prev.m){ 
    
 
    

            prev.m = doc.m; 
    
 
    

            prev.name = doc.m; 
    
 
    

            prev.country = doc.country; 
    
 
    

          } 
    
 
    

        }, 
    
 
    
condition:{m:{ 
     $gt:90}}, 
    
 
    
finalize:function(prev){ 
    
 
    

          prev.m = prev.name+" comes from "+prev.country+" ,Math score is "+prev.m; 
    
 
    

        } 
    
 
    

       } 
    
 
    

      })



  4.函数格式化分组键



  如果集合中出现键 CounrtycounTry同时存在

$keyf: 
     function(doc){ 
    
 
    

        if(doc.country){ 
    
 
    
return
 
    

        } 
    
 
    
return
 
    

      }



十五、常用命令举例



  1.查询服务器版本号和主机操作系统

db.runCommand({buildInfo:1})



  2查询执行集合的详细信息,大小,空间,索引等

db.runCommand({collStats:"persons"})



  3查看操作本集合最后一次错误信息

db.runCommand({getLastError:"persons"})



十六、固定集合



  1.特性



    固定集合默认是没有索引的就算是_id也是没有索引的



    由于不需分配新的空间他的插入速度是非常快的



    固定集合的顺是确定的导致查询速度是非常快的



    最适合就是日志管理



  2.创建固定集合



    创建一个新的固定集合要求大小是100个字节,可以存储文档10个

db.createCollection("mycoll",{size:100,capped:true,max:10})



    把一个普通集合转换成固定集合

db.runCommand({convertToCapped:"persons",size:1000})



  3.对固定集合反向排序,默认情况是插入的顺序排序

db.mycoll.find().sort({$natural:-1})



十七、GridFS



  GridFS是mongoDB自带的文件系统他用二进制的形式存储文件,大型文件系统的绝大多是特性GridFS全可以完成



  使用 GridFS使用mongofiles.exe命令行



  1.上传文件

mongofiles -d foobar -l "E:\1.jpg" put "1.jpg"



  2.查看文件内容

mongofiles -d foobar get "1.jpg"



  3.查看所有文件

mongofiles -d foobar list



  4.删除已经存在的文件

mongofiles -d foobar delete '1.jpg'



十八、Eval



  1.服务器端运行eval

db.eval("function(name){return name}","Jim")



  2.javascript的存储,在服务器上保存js全局变量



    把变量加入到特殊集合system.js中

db.system.js.insert({_id:"uname",value:"Jim"})
db.eval("return uname") #用eval调用



    System.js相当于Oracle中的存储过程,因为value不单单可以写变量,还可以写函数体也就是javascript代码



十九、启动配置



  1.利用config配置文件来启动数据库改变端口为8888


    mongodb.conf文件



dbpath = D:\sortware\mongod\db



port = 8888



  启动文件



cd C:\Users\thinkpad\Desktop\MONGODB\mongodb-win32-x86_64-2.0.6



bin\mongod.exe --config ../mongodb.conf



  shell文件



  mongo 127.0.0.1:8888



  2.停止MongoDB服务



  1)ctrl+c 组合键可以关闭数据库



  2)admin数据库命令关闭数据



use



shutdownServer



  3.导出数据(中断其他操作)



  使用 mongoexport命令行



   -d指明使用的库



   -c指明要导出的表



   -o指明要导出的文件名



   -csv指定导出的csv格式



   -q过滤导出



   --type<json|csv|tsv>



  把数据好foobar中的persons导出

mongoexport



  导出其他主机数据库的文档

mongoexport



  4.导入数据(中断其他操作)



mongoimport



  5.运行时备份 mongodump.exe



    API: http://cn.docs.mongodb.org/manual/reference/mongodump



mongodump



  6.运行时恢复 mongorestore.exe



    API:http://cn.docs.mongodb.org/manual/reference/mongorestore



    恢复数据库



dropDatabase()



mongorestore



  7.mongoDB是文件数据库这其实就可以用拷贝文件的方式进行备份



  8.上锁和解锁

db.runCommand({fsync:1,lock:1}) #上锁
db.currentOp() #解锁



  9.数据修复



    当停电等不可逆转灾难来临的时候,由于mongodb的存储结构导致



    会产生垃圾数据,在数据恢复以后这垃圾数据依然存在,这是数据库



    提供一个自我修复的能力.使用起来很简单 



db.repairDatabase()



二十、用户管理



  1.添加用户



    为admin添加uspcat用户和foobar数据库的yunfengcheng用户

use



addUser("uspcat","123")



users.find()



  2.启用用户

db.auth("名称","密码")



  3.安全检查 --auth



    非foobar是不能操作数据库的,启用自己的用户才能访问



    非admin数据库的用户不能使用数据库命令,admin数据库中的数据经过认证为管理员用户



  4.用户删除操作

db.system.users.remove({user:"yunfengcheng"});



二十一、主从复制



  1.主数据库配置:

#主数据库地址



#主数据库端口号



#主数据库所在服务器



#确定我是主服务器



  从数据库配置:

dbpath = D:\mongodb\data\db\07\7777 #从数据库地址



#从数据库端口号



#从数据库所在服务器



#确定从数据库监听端口



#这个配置项(source)可以用shell动态添加



#确定自己是从服务器



  2.主从复制的其他设置项



   --only 从节点?指定复制某个数据库,默认是复制全部数据库



   --slavedelay 从节点?设置主数据库同步数据的延迟(单位是秒)



   --fastsync 从节点?以主数据库的节点快照为节点启动从数据库



   --autoresync 从节点?如果不同步则从新同步数据库



   --oplogSize 主节点?设置oplog的大小(主节点操作记录存储到local的oplog中



  3.利用shell动态添加和删除从节点



  我们只要对集合进行操作就可以动态操作主从关系



  挂接主节点:操作之前只留下从数据库服务

db.sources.insert({host:"127.0.0.1:8888"})



  删除已经挂接的主节点:操作之前只留下从数据库服务

db.sources.remove({host:"127.0.0.1:8888"})



二十二、副本集



  A是活跃的B和C是用于备份的,当A出现了故障,这时候集群根据权重算法推选出B为活跃的数据库,当A恢复后他自动又会变为备份数据库



  1.设置conf文件



  2.初始化副本集

use
 
    
runCommand({"replSetInitiate": 
    
 
    

        { 
    
 
    

          "_id":'child', 
    
 
    

          "members":[{ 
    
 
    

            "_id":1, 
    
 
    

            "host":"127.0.0.1:1111" 
    
 
    

          },{ 
    
 
    

            "_id":2, 
    
 
    

            "host":"127.0.0.1:2222" 
    
 
    

          },{ 
    
 
    

            "_id":3, 
    
 
    

            "host":"127.0.0.1:3333"   
    
 
    

          }] 
    
 
    

        } 
    
 
    

      })



  查看副本集状态:

rs.status()



  3.节点和初始化高级参数



     standard :常规节点:参与投票有可能成为活跃节点



     passive :副本节点:参与投票,但是不能成为活跃节点



     arbiter :仲裁节点:只是参与投票不复制节点也不能成为活跃节点



  4.高级参数



     Priority :0到1000之间 ,0代表是副本节点 ,1到1000是常规节点



     arbiterOnly : true 仲裁节点


members":[{ 
    
 
    

        "_id":1, 
    
 
    

        "host":"127.0.0.1:1111", 
    
 
    

        arbiterOnly : true 
    
 
    

      }]"



  5.读写分离



    一般情况下作为副本的节点是不能进行数据库读操作的,但是在读取密集型的系统中读写分离是十分必要的



    设置读写分离 slaveOkay : true



二十三、分片



  1.分片步骤



  1)创建一个配置服务器

shardServer.conf 
    
 
    

      dbpath=D:\mongodb\data\db\08\conf 
    
 
    

      port=2000 
    
 
    

      bind_ip=127.0.0.1 
    
 
    

      shardServer.bat 
    
 
    

      mongod --conf shardServer.conf



  2)创建路由服务器

mongos --port 1000 --configdb 127.0.0.1:2000



    shell文件: mongo 127.0.0.1:1000/admin



  3)添加2个分片数据库 8081和8082

shard8081.conf 
    
 
    

      dbpath=D:\mongodb\data\db\08\8081 
    
 
    

      port=8081 
    
 
    

      bind_ip=127.0.0.1 
    
 
    

      shard8081.bat 
    
 
    

      mongos --conf shard8081.conf 
    
 
    

      shard8081Shell.bat 
    
 
    

      mongo 127.0.0.1:8081/admin


  4)启动四个数据库服务器



    打开路由shell命令行,为集群添加分片(允许本地访问)"切记之前不能使用任何数据库语句"

runCommand({addshard:"127.0.0.1:8081",allowLocal:true}) 
    
 
    
runCommand({addshard:"127.0.0.1:8082",allowLocal:true})



  5)指定打开分片功能的数据库

db.runCommand({enablesharding:"foobar"})



  6)指定集合进行分片,并设置片键

db.runCommand({shardcollection:"foobar.persons",key:{_id:1}})



  7)插入大数据量进行测试



    进入分片8081查询数据条数

db.persons.find().count()



  2.查看配置库对于分片配置存储信息

db.printShardingStatus()



  3.查看集群对persons的自动分片机制配置信息

find()

{ "_id" : "shard0000", "host" : "127.0.0.1:8081" } 
    
 
    

      { "_id" : "shard0001", "host" : "127.0.0.1:8082" }