如发现博文存在问题,可以随时滴滴我

Windows下初体验MongoDB数据库

目录

一、MongoDB的安装

1.1 MongoDB的下载安装

1.2 环境变量的配置

 1.3 启动Mongo服务

1.4 初体验

二、MongoDB基本命令

2.1 基本命令1

2.2 基本命令2

2.2.1 增加数据

2.2.2 修改数据

 2.2.3 删除

三、用JavaScript来写命令

四、MongoDB插入的批量操作

五、MongoDB Updata常见错误

5.1 在数据库中准备数据

5.2 修改

 六、初始Update修改器

6.1 $set修改器

6.2 $unset修改器

6.3 $inc修改器

6.4 multi选项用法

6.5 upsert选项用法

 七、Update数组修改器

7.1 $push修改器

7.2 $ne修改器

7.3 $addToSet修改器

7.4 $each修改器

7.5 $pop修改器

7.6 数组定位修改

七、findAndModify

7.1 runCommand()

7.2 findAndModify()

 八、MongoDB查询_不等修饰符

  九、MongoDB查询_多条件查询

  十、MongoDB查询_数组查询

10.1 $all修饰符

10.2 $in修饰符

10.3 $size修饰符

 10.4 $slice修饰符

十一、MongoDB查询_参数使用方法

十二、MongoDB查询_如何在js文本中使用

十三、MongoDB索引_构造百万级数据表

十四、MongoDB索引_建立索引

十五、MongoDB索引_复合索引

 15.1 复合索引

15.2 删除索引

十六、MongoDB索引_全文索引

16.1 插入数据

16.2 建立全文索引

十七、MongoDB用户的创建删除和管理

17.1 创建管理员

十八、MongoDB数据库的备份和还原

十九、MongoDB数据库的图形化界面


MongoDB一律采用小驼峰命名法

一、MongoDB的安装

1.1 MongoDB的下载安装

 

1.2 环境变量的配置

右键此电脑,点击属性,点击高级系统设置,点击环境变量

 进入刚才安装的MongoDB的bin目录,复制路径,添加在环境变量中

 1.3 启动Mongo服务

命令行中执行 mongod

 手动创建完data/db目录之后,再次执行mongod

说明Mongo服务已经启动成功 

1.4 初体验

再次打开一个终端,执行mongo命令连接数据库

 

二、MongoDB基本命令

2.1 基本命令1

 

2.2 基本命令2

2.2.1 增加数据

  1. show dbs 查看所有数据库
  2. use user 使用该数据库(没有则自动创建)
  3. db 查看当前数据库
  4. show collections 查看当前数据库下的集合
  5. db.user.insert({"name":"Hamy"}) 给user集合中插入一条数据
  6. db.user.find() 查看当前集合下的所有数据
  7. db.user.findOne() 查看当前集合下的第一条数据

 MongoDB会自动添加一条_id索引

 再次插入两条数据,然后查询

2.2.2 修改数据

db.user.updata({"name":"Hamy"},{"name":"Hamy","age",18})  修改name为Hamy的用户age为18,没有则创建

 2.2.3 删除

  1. db.user.remove({"name":"Hamy"}) 删除数据
  2. db.user.drop() 删除集合
  3. db.user.dropDatabase() 删除数据库

三、用JavaScript来写命令

新建一个js文件goTask.js

  1. var userName="xueshuai"; //定义一个用户名
  2. var password="xueshuai"; //定义一个密码
  3. var jsonDatabase={"loginName":userName,"loginPassword":password}; //生成json字符串
  4. var db=connect('user'); //相当于在终端中执行use user,进入数据库
  5. db.login.insert(jsonDatabase) //给该数据库中login集合插入一条数据
  6. print('[demo]:log print success') //打印插入成功

打开终端进入该js的目录下执行mongo goTask.js

最下面会有日志打印成功 

接下来查看当前数据库中是否存在该数据

首先打开终端执行mongo命令,连接数据库

其次"查看所有数据库","使用数据库","查看所有集合","查询该集合下的所有数据",可以看到数据存入成功

四、MongoDB插入的批量操作

  1. db.test.insert([{"_id":1},{"_id":2},{"_id":3}]) //执行这条命令会在test集合中插入三条数据
  2. db.test.find() //执行这条命令会查找该test集合中的所有数据

 在实际工作中建议采用批量插入的方法插入数据,循环插入耗费性能(循环插入可能需要584ms,批量插入可能只需要84ms)

  1. var startTime = (new Date()).getTime();//获取开始时间
  2. var db=connect('log');//连接数据库
  3. //循环插入
  4. /* for(let i=0;i<1000;i++){
  5. db.test.insert({num:i});//插入数据
  6. } */
  7. //批量插入
  8. var tempArray = [];
  9. for(let i=0;i<1000;i++){
  10. tempArray.push({num:i});
  11. }
  12. db.test.insert(tempArray)//插入数组
  13. var runTime = (new Date()).getTime() - startTime;
  14. print("[demo]This run is " + runTime + 'ms')

五、MongoDB Updata常见错误

5.1 在数据库中准备数据

  1. var workmate1={
  2. name:'JSPang',
  3. age:33,
  4. sex:1,
  5. job:'PHP后端',
  6. skill:{
  7. skillOne:'HTML+CSS',
  8. skillTwo:'JavaScript',
  9. skillThree:'PHP'
  10. },
  11. regeditTime:new Date()
  12. }
  13. ...
  1. var db=connect('company');//连接数据库
  2. var workmateArray=[workmate1,workmate2,workmate3];//将所有的数据放在一个数组中
  3. db.workmate.insert(workmateArray);//批量插入数据
  4. print('[success]:The data was inserted successfully')//打印

打开VSCode,首先执行mongo命令,然后加载该js文件,最后去集合中查找有没有数据

5.2 修改

情景:修改LiLy的性别

  1. /****错误示范****/
  2. var db=connect('company')//连接数据库
  3. db.workmate.update({name:'LiLy'},{sex:1})//修改name为LiLy的性别为1
  4. print('[update]:The data was updated successfully')
  5. //看似并没有任何问题,但是当执行完这个文件之后,LiLy的资料只剩一个sex为1,其余资料全被删除
  1. /****正确示范****/
  2. //在一个对象中修改值
  3. var workmate3={
  4. name:'LiLy',
  5. age:18,
  6. sex:1,
  7. job:'UI',
  8. skill:{
  9. skillOne:'PhotoShop',
  10. skillTwo:'UI',
  11. skillThree:'PPT'
  12. },
  13. regeditTime:new Date()
  14. }
  15. var db=connect('company')
  16. //先查找要修改的数据,用修改后的wormate3覆盖原先的数据
  17. db.workmate.update({name:'LiLy'},workmate3)
  18. print('[update]:The data was updated successfully')

 六、初始Update修改器

6.1 $set修改器

  1. //修改workmate集合中name为LiLy的性别为0,年龄为20,且不会影响到其他字段
  2. db.workmate.update({name:'LiLy'},{"$set":{sex:0,age:20}})
  3. //内嵌数据的修改,skill下有skillOne、skillTwo、skillThree
  4. db.workmate.update({name:'LiLy'},{$set:{"skill.skillThree":"word"}})

6.2 $unset修改器

  1. //找到name为LiLy的用户删除年龄,age后面的值可以为空,也可以为-1,可以为任意值,只关注key值
  2. db.workmate.update({name:'LiLy'},{$unset:{age:''}})
  3. //找到name为LiLy的用户,添加年龄,使用$set修饰符
  4. db.workmate.update({name:'LiLy'},{"$set":{age:20}})

6.3 $inc修改器

  1. //找到name为LiLy的用户,修改年龄为18,使用$inc修饰符,在原来的年龄基础上-2
  2. db.workmate.update({name:'LiLy'},{"$inc":{age:-2}})

6.4 multi选项用法

  1. //给所有的用户添加一个interest字段
  2. //multi:true(查找到第一条继续往下查找) false(只查找一条,默认)
  3. db.workmate.update({},{"$set":{interest:[]}},{multi:true})

6.5 upsert选项用法

  1. //修改name为xiaoWang的用户年龄为20
  2. //upsert:true(如果没找到就添加) false(如果没找到就不添加,默认)
  3. db.workmate.update({name:"xiaoWang"},{"$set":{age:20}},{upsert:true})

 七、Update数组修改器

7.1 $push修改器

  1. //给name为xiaoWang的用户添加interest为draw
  2. db.workmate.update({name:"xiaoWang"},{$push:{interest:'draw'}})
  3. //给name为LiLy的用户添加skill的skillFour为draw,依然是以数组的形式
  4. db.workmate.update({name:"LiLy"},{$push:{"skill.skillFour":'draw'}})

7.2 $ne修改器

  1. //查找name为xiaoWang的用户的interest里面有没有playGame的爱好,如果没有则添加,有则不添加
  2. db.workmate.update({name:"xiaoWang",interest:{$ne:'playGame'}},{$push:{interest:'Game'}})

7.3 $addToSet修改器

  1. //$ne的升级版
  2. //查找name为xiaoWang的用户有没有readBook的interest,没有则添加,有则不添加
  3. db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:'readBook'}})

7.4 $each修改器

  1. //查找name为xiaoWang的用户批量添加interest,首先定义变量保存要添加的内容,使用$each批量添加
  2. var newInterests = ['Sing','Dance','Code'];
  3. db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:{$each:newInterests}}})

7.5 $pop修改器

  1. //$pop 1(从末端开始删除) -1(从开始位置删除)
  2. //查找name为xiaoWang的用户,删除interest中最后一项
  3. db.workmate.update({name:"xiaoWang"},{$pop:{interest:1}})

7.6 数组定位修改

  1. //查找name为xiaoWang的用户,修改interest的下标为2的改为Code
  2. db.workmate.update({name:"xiaoWang"},{$set:{"interest.2":"Code"}})

七、findAndModify

7.1 runCommand()

  1. //给所有sex为1的用户添加一个字段money为1000
  2. //第一个false表示如果没有找到sex为1的用户不增加,true表示查找完之后还会继续查找(找到所有sex为1的用户)
  3. db.workmate.update({sex:1},{$set:{money:1000}},false,true)
  4. var resultMessage = db.runCommand({getLastError:1})//查看返回值
  5. /*
  6. //执行安全操作
  7. if(resultMessage.updatedExisting){
  8. }else{
  9. }
  10. */
  11. printjson(resultMessage)
  1. //可以通过如下命令查看当前数据库是否连接成功
  2. db.runCommand({ping:1})
  3. //成功则会返回
  4. { "ok" : 1 }

7.2 findAndModify()

  1. //定义一个对象,传入参数
  2. var myModify = {
  3. findAndModify:"workmate",//修改的集合
  4. query:{ name:"JSPang" },//查找条件
  5. update:{$set:{age:18}},//修改为
  6. new:true//true为修改后的值,false为修改前的值
  7. }
  8. //定义一个变量接收返回值
  9. var resultMessage = db.runCommand(myModify);
  10. //将返回值打印出来
  11. printjson(resultMessage);

 八、MongoDB查询_不等修饰符

  1. //查询skill的skillOne为HTML+CSS的用户
  2. db.workmate.find(
  3. {"skill.skillOne":"HTML+CSS"},//查询条件
  4. {name:true,"skill.skillOne":true,"_id":false} //返回规则(true为需要返回,false为不需要返回)
  5. )

  1. //查询年龄大于等于25小于等于30的用户
  2. db.workmate.find(
  3. {age:{$lte:30,$gte:25}},
  4. {name:true,"skill.skillOne":true,age:true,"_id":false}
  5. )
  1. //查找注册日期大于01/01/2018日期的用户
  2. var startDate = new Date('01/01/2018');
  3. db.workmate.find(
  4. {regeditTime:{$gt:startDate}},
  5. {name:true,"skill.skillOne":true,age:true,"_id":false}
  6. )

  九、MongoDB查询_多条件查询

  1. //查询age为25或33的用户(多条件查询)
  2. //$in 一个key多个value查询
  3. db.workmate.find(
  4. {age:{$in:[25,33]}},
  5. {name:true,"skill.skillOne":true,age:true,_id:false}
  6. )
  7. //查询age除了25和33的用户
  8. //$nin 不包含查询
  9. db.workmate.find(
  10. {age:{$nin:[25,33]}},
  11. {name:true,"skill.skillOne":true,age:true,_id:false}
  12. )
  1. //查询age大于等于30或者skill.skillThree等于PHP的用户
  2. //$or 多key多value查询
  3. db.workmate.find(
  4. {$or:[
  5. {age:{$gte:30}},
  6. {"skill.skillThree":"PHP"}
  7. ]},
  8. {name:true,"skill.skillThree":true,age:true,_id:false}
  9. )
  1. //查询age大于等于20小于等于30之外的用户
  2. //$not
  3. db.workmate.find(
  4. {age:{$not:{$lte:30,$gte:20}}},
  5. {name:true,"skill.skillThree":true,age:true,_id:false}
  6. )

  十、MongoDB查询_数组查询

  1. //查询interest为'画画','聚会','看电影'的用户
  2. db.workmate.find(
  3. {interest:['画画','聚会','看电影']},
  4. {name:true,interest:true,age:true,_id:false}
  5. )
  6. //查询interest中有'画画'的用户
  7. db.workmate.find(
  8. {interest:'画画'},//'画画'不能加中括号,加中括号属于完全匹配
  9. {name:true,interest:true,age:true,_id:false}
  10. )

10.1 $all修饰符

  1. //查询interest中既有'看电影',又有'看书'的用户
  2. db.workmate.find(
  3. {interest:{$all:['看电影','看书']}},
  4. {name:true,interest:true,age:true,_id:false}
  5. )

10.2 $in修饰符

  1. //查询interest中有'看电影'或'看书'的用户
  2. //$in
  3. db.workmate.find(
  4. {interest:{$in:['看电影','看书']}},
  5. {name:true,interest:true,age:true,_id:false}
  6. )

10.3 $size修饰符

  1. //查询interest中有5项的用户
  2. //$size
  3. db.workmate.find(
  4. {interest:{$size:5}},
  5. {name:true,interest:true,age:true,_id:false}
  6. )

 10.4 $slice修饰符

  1. //查询interest中有3项的用户并且返回第一项
  2. //$slice
  3. db.workmate.find(
  4. {interest:{$size:3}},
  5. {name:true,interest:{$slice:1},age:true,_id:false}
  6. )
  7. //显示前两项
  8. db.workmate.find(
  9. {interest:{$size:3}},
  10. {name:true,interest:{$slice:2},age:true,_id:false}
  11. )
  12. //显示最后一项
  13. db.workmate.find(
  14. {interest:{$size:3}},
  15. {name:true,interest:{$slice:-1},age:true,_id:false}
  16. )
  17. //显示区间项
  18. //显示从下标为0项到下标为3项
  19. db.workmate.find(
  20. {interest:{$size:5}},
  21. {name:true,interest:{$slice:[0,3]},age:true,_id:false}
  22. )

十一、MongoDB查询_参数使用方法

  1. //查询所有,分页显示
  2. //分页 每页显示两个 年龄从小到大
  3. //sort 1(从小到大) -1(从大到小)
  4. db.workmate.find(
  5. {},
  6. {name:true,age:true,_id:false}
  7. ).limit(2).skip(0).sort({age:1})
  1. //查询age大于30的用户
  2. //$where
  3. db.workmate.find(
  4. {$where:"this.age>30"},//this指代的是workmate集合
  5. {name:true,age:true,_id:false}
  6. )

 能普通查询尽量不使用$where查询

  • 不安全
  • 加重了数据库的负担

十二、MongoDB查询_如何在js文本中使用

  1. //在js中写下如下代码,终端中执行mongo,然后load('当前文件路径.js')就可以执行
  2. //hasNext()
  3. var db = connect('company');
  4. var result = db.workmate.find();//将查到的所有数据赋值给一个变量,最后打印这个变量
  5. //方法一:while
  6. // while(result.hasNext()){
  7. // printjson(result.next())
  8. // }
  9. //方法二:forEach()
  10. result.forEach(function(result){
  11. printjson(result);
  12. })

十三、MongoDB索引_构造百万级数据表

首先需要安装node.js环境

  • 使用node.js是为了测试随机数和随即用户名是否正确
  • 在执行mongo命令,执行load('当前文件路径.js'),运行这段js存储在MongoDB的时候,不能有console.log,mongoShell不支持
  1. //生成随机数
  2. function GetRandomNum(min,max){
  3. let range = max-min;//随机区间 10
  4. let rand = Math.random();//随机数 0-1
  5. return (min+Math.round(rand*range));//10+([0-1]*10)
  6. }
  7. //console.log(GetRandomNum(10,20))
  8. //生成随机用户名
  9. function GetRadomUserName(min,max){
  10. let tempStringArray = "123456789qwertyuiopasdfghjklzxcvbnm".split("");//是个数组
  11. let outputtext = "";//输出的用户名
  12. for(let i=1;i<GetRandomNum(min,max);i++){//用户名的长度是一个随机数
  13. outputtext= outputtext + tempStringArray[GetRandomNum(0,tempStringArray.length-1)]//用户名应该是由tempStringArray数组中的每一项拼成
  14. }
  15. return outputtext;
  16. }
  17. //console.log(GetRadomUserName(7,16));
  18. //批量插入两百万条数据
  19. var startTime = (new Date()).getTime();//获取开始时间
  20. var tempInfo=[];
  21. for(let i=0;i<2000000;i++){
  22. tempInfo.push({
  23. username:GetRadomUserName(7,16),
  24. regediteTime:new Date(),
  25. randNum0:GetRandomNum(100000,999999),
  26. randNum1:GetRandomNum(100000,999999),
  27. randNum2:GetRandomNum(100000,999999),
  28. randNum3:GetRandomNum(100000,999999),
  29. randNum4:GetRandomNum(100000,999999),
  30. randNum5:GetRandomNum(100000,999999),
  31. randNum6:GetRandomNum(100000,999999),
  32. randNum7:GetRandomNum(100000,999999),
  33. randNum8:GetRandomNum(100000,999999),
  34. randNum9:GetRandomNum(100000,999999),
  35. })
  36. }
  37. var db = connect('company');//连接数据库
  38. db.randomInfo.drop();//先删除原有的randomInfo库
  39. db.randomInfo.insert(tempInfo);//然后添加现在的库
  40. var endTime = (new Date()).getTime() - startTime;//计算耗时
  41. print("[总共耗时]:----------"+endTime+"ms")

由图可见,还是很快的

十四、MongoDB索引_建立索引

  1. var startTime = (new Date()).getTime();
  2. var db = connect('company');
  3. var rs = db.randomInfo.find({username:'9wobojo'});//从数据库中任意取到的一个username
  4. rs.forEach(rs => printjson(rs) );//打印当前这个数据
  5. var runTime = new Date().getTime() - startTime;
  6. print('[demo]:this run time is '+runTime+'ms');
  7. //普通查询可能需要1000-2000ms的时间
  8. //查看索引
  9. db.randomInfo.getIndexes()
  10. //数组中有几个对象就有几个索引,mongodb默认有一个id索引,最多支持64个索引
  11. [
  12. {
  13. "v" : 2,
  14. "key" : {
  15. "_id" : 1
  16. },
  17. "name" : "_id_",
  18. "ns" : "company.randomInfo"
  19. }
  20. ]
  21. //建立索引
  22. db.randomInfo.ensureIndex({username:1})
  23. //建立索引之后再次查看索引,可以看到有了两个索引
  24. [
  25. {
  26. "v" : 2,
  27. "key" : {
  28. "_id" : 1
  29. },
  30. "name" : "_id_",
  31. "ns" : "company.randomInfo"
  32. },
  33. {
  34. "v" : 2,
  35. "key" : {
  36. "username" : 1
  37. },
  38. "name" : "username_1",
  39. "ns" : "company.randomInfo"
  40. }
  41. ]
  42. //建立索引之后再次查询可能只需要几毫秒

十五、MongoDB索引_复合索引

 15.1 复合索引

 所谓的复合索引,就是多条索引查询

首先再建一条索引

db.randomInfo.ensureIndex({randNum0:1})

username索引是字符串索引

randNum索引是数字索引

MongoDB根据索引查询的顺序是通过如下查询的

  1. > db.randomInfo.getIndexes()
  2. [
  3. {
  4. "v" : 2,
  5. "key" : {
  6. "_id" : 1
  7. },
  8. "name" : "_id_",
  9. "ns" : "company.randomInfo"
  10. },
  11. {
  12. "v" : 2,
  13. "key" : {
  14. "username" : 1
  15. },
  16. "name" : "username_1",
  17. "ns" : "company.randomInfo"
  18. },
  19. {
  20. "v" : 2,
  21. "key" : {
  22. "randNum0" : 1
  23. },
  24. "name" : "randNum0_1",
  25. "ns" : "company.randomInfo"
  26. }
  27. ]

如果想优先使用randNum索引查询需要使用hint方法

db.randomInfo.find({username:'e89aamcvz',randNum0:942055}).hint({randNum0:true})

15.2 删除索引

db.randomInfo.dropIndex('randNum0_1')

括号里的内容填写的是该索引的name

通过如下命令查看索引

db.randomInfo.getIndexes()

十六、MongoDB索引_全文索引

16.1 插入数据

首先测试,先在info集合中插入两条数据

  1. db.info.insert({contextInfo:"I am a programmer, I love life, love family. Every day after work, I write a diary."})
  2. db.info.insert({contextInfo:"I am a programmer, I love PlayGame, love drink. Every day after work, I playGame and drink."})

16.2 建立全文索引

db.info.ensureIndex({contextInfo:'text'})
  1. //查询全文中有programmer的内容
  2. db.info.find({$text:{$search:'programmer'}})
  3. //查询全文中有programmer 或 family 或 diary 或 drink的内容
  4. db.info.find({$text:{$search:'programmer family diary drink'}})
  5. //查询全文中有programmer 或 family 或 diary的内容,但是不查找drink的内容
  6. db.info.find({$text:{$search:'programmer family diary -drink'}})
  7. //查询全文中有"love PlayGame"或drink的内容
  8. //如果两个词之间有空格,MongoDB提供了转义符的形式 \" "
  9. db.info.find({$text:{$search:"\"love PlayGame\" drink"}})

十七、MongoDB用户的创建删除和管理

17.1 创建管理员

mongo服务启动之后,首先需要进入admin数据库

use admin

 然后创建管理员

  1. //创建管理员
  2. db.createUser({
  3. user:'jspang',//用户名
  4. pwd:'123456',//密码
  5. customData:{//管理员数据
  6. name:'技术胖',
  7. email:'web0432@126.com',
  8. age:18
  9. },
  10. roles:[//权限
  11. {
  12. role:"readWrite",//拥有读写权限
  13. db:"company"//对company数据库拥有权限
  14. },
  15. 'read'//其他用户拥有只读权限
  16. ]
  17. })
  18. //查询存在的管理员
  19. db.system.users.find()
  20. //删除管理员
  21. db.system.users.remove({user:'jspang'})

建权

  1. //管理员账号密码
  2. db.auth("jspang","123456")
  3. //建权之后启动mongod使用
  4. mongod --auth
  5. //启用mongo服务时使用
  6. //mongo -u 用户名 -p 密码 ip:端口/admin
  7. mongo -u jspang -p 123456 127.0.0.1:27017/admin
  8. //进入数据库
  9. use company
  10. //查询集合
  11. show collections
  12. ...

十八、MongoDB数据库的备份和还原

首先开启服务

然后执行备份命令

  1. mongodump
  2. --host 127.0.0.1 //ip地址
  3. --port 27017 //端口
  4. --out D:/backup //备份存在的目录
  5. --collection randomInfo //需要备份的集合
  6. --db company //需要备份的数据库
  7. --username username //用户名
  8. --password password //密码
  9. 例:
  10. //备份所有数据到D:/backup目录
  11. mongodump --host 127.0.0.1 --port 27017 --out D:/backup/

恢复命令

  1. mongorestore
  2. --host 127.0.0.1 //ip
  3. --port 27017 //端口
  4. --username username //用户名
  5. --password password //密码
  6. <path to the backup> //备份的路径
  7. 例:
  8. mongorestore --host 127.0.0.1 --port 27017 D:/backup/

十九、MongoDB数据库的图形化界面

启动图形化界面之前,首先需要启动mongod服务

 可以看到MongoDB下的所有数据库,点击数据库可显示集合,点击集合可查看集合中数据

 

查询数据

修改数据

创建集合

 

 

MongoDB基础教程到此结束,皆根据JSPang的个人博客教程记录的个人笔记。

不积跬步,无以至千里

posted @ 2020-01-05 19:12  webxue  阅读(310)  评论(0编辑  收藏  举报