Windows下初体验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 增加数据
- show dbs 查看所有数据库
- use user 使用该数据库(没有则自动创建)
- db 查看当前数据库
- show collections 查看当前数据库下的集合
- db.user.insert({"name":"Hamy"}) 给user集合中插入一条数据
- db.user.find() 查看当前集合下的所有数据
- db.user.findOne() 查看当前集合下的第一条数据
MongoDB会自动添加一条_id索引
再次插入两条数据,然后查询
2.2.2 修改数据
db.user.updata({"name":"Hamy"},{"name":"Hamy","age",18}) 修改name为Hamy的用户age为18,没有则创建
2.2.3 删除
- db.user.remove({"name":"Hamy"}) 删除数据
- db.user.drop() 删除集合
- db.user.dropDatabase() 删除数据库
三、用JavaScript来写命令
新建一个js文件goTask.js
- var userName="xueshuai"; //定义一个用户名
- var password="xueshuai"; //定义一个密码
- var jsonDatabase={"loginName":userName,"loginPassword":password}; //生成json字符串
- var db=connect('user'); //相当于在终端中执行use user,进入数据库
- db.login.insert(jsonDatabase) //给该数据库中login集合插入一条数据
-
- print('[demo]:log print success') //打印插入成功
打开终端进入该js的目录下执行mongo goTask.js
最下面会有日志打印成功
接下来查看当前数据库中是否存在该数据
首先打开终端执行mongo命令,连接数据库
其次"查看所有数据库","使用数据库","查看所有集合","查询该集合下的所有数据",可以看到数据存入成功
四、MongoDB插入的批量操作
- db.test.insert([{"_id":1},{"_id":2},{"_id":3}]) //执行这条命令会在test集合中插入三条数据
-
- db.test.find() //执行这条命令会查找该test集合中的所有数据
在实际工作中建议采用批量插入的方法插入数据,循环插入耗费性能(循环插入可能需要584ms,批量插入可能只需要84ms)
- var startTime = (new Date()).getTime();//获取开始时间
- var db=connect('log');//连接数据库
- //循环插入
- /* for(let i=0;i<1000;i++){
- db.test.insert({num:i});//插入数据
- } */
-
- //批量插入
- var tempArray = [];
- for(let i=0;i<1000;i++){
- tempArray.push({num:i});
- }
- db.test.insert(tempArray)//插入数组
-
- var runTime = (new Date()).getTime() - startTime;
- print("[demo]This run is " + runTime + 'ms')
五、MongoDB Updata常见错误
5.1 在数据库中准备数据
- var workmate1={
- name:'JSPang',
- age:33,
- sex:1,
- job:'PHP后端',
- skill:{
- skillOne:'HTML+CSS',
- skillTwo:'JavaScript',
- skillThree:'PHP'
- },
- regeditTime:new Date()
- }
- ...
- var db=connect('company');//连接数据库
- var workmateArray=[workmate1,workmate2,workmate3];//将所有的数据放在一个数组中
- db.workmate.insert(workmateArray);//批量插入数据
- print('[success]:The data was inserted successfully')//打印
打开VSCode,首先执行mongo命令,然后加载该js文件,最后去集合中查找有没有数据
5.2 修改
情景:修改LiLy的性别
- /****错误示范****/
-
- var db=connect('company')//连接数据库
- db.workmate.update({name:'LiLy'},{sex:1})//修改name为LiLy的性别为1
- print('[update]:The data was updated successfully')
-
- //看似并没有任何问题,但是当执行完这个文件之后,LiLy的资料只剩一个sex为1,其余资料全被删除
- /****正确示范****/
-
- //在一个对象中修改值
- var workmate3={
- name:'LiLy',
- age:18,
- sex:1,
- job:'UI',
- skill:{
- skillOne:'PhotoShop',
- skillTwo:'UI',
- skillThree:'PPT'
- },
- regeditTime:new Date()
- }
- var db=connect('company')
- //先查找要修改的数据,用修改后的wormate3覆盖原先的数据
- db.workmate.update({name:'LiLy'},workmate3)
- print('[update]:The data was updated successfully')
六、初始Update修改器
6.1 $set修改器
- //修改workmate集合中name为LiLy的性别为0,年龄为20,且不会影响到其他字段
- db.workmate.update({name:'LiLy'},{"$set":{sex:0,age:20}})
-
- //内嵌数据的修改,skill下有skillOne、skillTwo、skillThree
- db.workmate.update({name:'LiLy'},{$set:{"skill.skillThree":"word"}})
6.2 $unset修改器
- //找到name为LiLy的用户删除年龄,age后面的值可以为空,也可以为-1,可以为任意值,只关注key值
- db.workmate.update({name:'LiLy'},{$unset:{age:''}})
- //找到name为LiLy的用户,添加年龄,使用$set修饰符
- db.workmate.update({name:'LiLy'},{"$set":{age:20}})
6.3 $inc修改器
- //找到name为LiLy的用户,修改年龄为18,使用$inc修饰符,在原来的年龄基础上-2
- db.workmate.update({name:'LiLy'},{"$inc":{age:-2}})
6.4 multi选项用法
- //给所有的用户添加一个interest字段
- //multi:true(查找到第一条继续往下查找) false(只查找一条,默认)
- db.workmate.update({},{"$set":{interest:[]}},{multi:true})
6.5 upsert选项用法
- //修改name为xiaoWang的用户年龄为20
- //upsert:true(如果没找到就添加) false(如果没找到就不添加,默认)
- db.workmate.update({name:"xiaoWang"},{"$set":{age:20}},{upsert:true})
七、Update数组修改器
7.1 $push修改器
- //给name为xiaoWang的用户添加interest为draw
- db.workmate.update({name:"xiaoWang"},{$push:{interest:'draw'}})
- //给name为LiLy的用户添加skill的skillFour为draw,依然是以数组的形式
- db.workmate.update({name:"LiLy"},{$push:{"skill.skillFour":'draw'}})
7.2 $ne修改器
- //查找name为xiaoWang的用户的interest里面有没有playGame的爱好,如果没有则添加,有则不添加
- db.workmate.update({name:"xiaoWang",interest:{$ne:'playGame'}},{$push:{interest:'Game'}})
7.3 $addToSet修改器
- //$ne的升级版
- //查找name为xiaoWang的用户有没有readBook的interest,没有则添加,有则不添加
- db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:'readBook'}})
7.4 $each修改器
- //查找name为xiaoWang的用户批量添加interest,首先定义变量保存要添加的内容,使用$each批量添加
- var newInterests = ['Sing','Dance','Code'];
- db.workmate.update({name:"xiaoWang"},{$addToSet:{interest:{$each:newInterests}}})
7.5 $pop修改器
- //$pop 1(从末端开始删除) -1(从开始位置删除)
- //查找name为xiaoWang的用户,删除interest中最后一项
- db.workmate.update({name:"xiaoWang"},{$pop:{interest:1}})
7.6 数组定位修改
- //查找name为xiaoWang的用户,修改interest的下标为2的改为Code
- db.workmate.update({name:"xiaoWang"},{$set:{"interest.2":"Code"}})
七、findAndModify
7.1 runCommand()
- //给所有sex为1的用户添加一个字段money为1000
- //第一个false表示如果没有找到sex为1的用户不增加,true表示查找完之后还会继续查找(找到所有sex为1的用户)
- db.workmate.update({sex:1},{$set:{money:1000}},false,true)
-
- var resultMessage = db.runCommand({getLastError:1})//查看返回值
- /*
- //执行安全操作
- if(resultMessage.updatedExisting){
- }else{
- }
- */
- printjson(resultMessage)
- //可以通过如下命令查看当前数据库是否连接成功
- db.runCommand({ping:1})
-
- //成功则会返回
- { "ok" : 1 }
7.2 findAndModify()
- //定义一个对象,传入参数
- var myModify = {
- findAndModify:"workmate",//修改的集合
- query:{ name:"JSPang" },//查找条件
- update:{$set:{age:18}},//修改为
- new:true//true为修改后的值,false为修改前的值
- }
- //定义一个变量接收返回值
- var resultMessage = db.runCommand(myModify);
- //将返回值打印出来
- printjson(resultMessage);
八、MongoDB查询_不等修饰符
- //查询skill的skillOne为HTML+CSS的用户
- db.workmate.find(
- {"skill.skillOne":"HTML+CSS"},//查询条件
- {name:true,"skill.skillOne":true,"_id":false} //返回规则(true为需要返回,false为不需要返回)
- )
- //查询年龄大于等于25小于等于30的用户
- db.workmate.find(
- {age:{$lte:30,$gte:25}},
- {name:true,"skill.skillOne":true,age:true,"_id":false}
- )
- //查找注册日期大于01/01/2018日期的用户
- var startDate = new Date('01/01/2018');
- db.workmate.find(
- {regeditTime:{$gt:startDate}},
- {name:true,"skill.skillOne":true,age:true,"_id":false}
- )
九、MongoDB查询_多条件查询
- //查询age为25或33的用户(多条件查询)
- //$in 一个key多个value查询
- db.workmate.find(
- {age:{$in:[25,33]}},
- {name:true,"skill.skillOne":true,age:true,_id:false}
- )
-
- //查询age除了25和33的用户
- //$nin 不包含查询
- db.workmate.find(
- {age:{$nin:[25,33]}},
- {name:true,"skill.skillOne":true,age:true,_id:false}
- )
- //查询age大于等于30或者skill.skillThree等于PHP的用户
- //$or 多key多value查询
- db.workmate.find(
- {$or:[
- {age:{$gte:30}},
- {"skill.skillThree":"PHP"}
- ]},
- {name:true,"skill.skillThree":true,age:true,_id:false}
- )
- //查询age大于等于20小于等于30之外的用户
- //$not
- db.workmate.find(
- {age:{$not:{$lte:30,$gte:20}}},
- {name:true,"skill.skillThree":true,age:true,_id:false}
- )
十、MongoDB查询_数组查询
- //查询interest为'画画','聚会','看电影'的用户
- db.workmate.find(
- {interest:['画画','聚会','看电影']},
- {name:true,interest:true,age:true,_id:false}
- )
-
- //查询interest中有'画画'的用户
- db.workmate.find(
- {interest:'画画'},//'画画'不能加中括号,加中括号属于完全匹配
- {name:true,interest:true,age:true,_id:false}
- )
10.1 $all修饰符
- //查询interest中既有'看电影',又有'看书'的用户
- db.workmate.find(
- {interest:{$all:['看电影','看书']}},
- {name:true,interest:true,age:true,_id:false}
- )
10.2 $in修饰符
- //查询interest中有'看电影'或'看书'的用户
- //$in
- db.workmate.find(
- {interest:{$in:['看电影','看书']}},
- {name:true,interest:true,age:true,_id:false}
- )
10.3 $size修饰符
- //查询interest中有5项的用户
- //$size
- db.workmate.find(
- {interest:{$size:5}},
- {name:true,interest:true,age:true,_id:false}
- )
10.4 $slice修饰符
- //查询interest中有3项的用户并且返回第一项
- //$slice
- db.workmate.find(
- {interest:{$size:3}},
- {name:true,interest:{$slice:1},age:true,_id:false}
- )
-
- //显示前两项
- db.workmate.find(
- {interest:{$size:3}},
- {name:true,interest:{$slice:2},age:true,_id:false}
- )
-
- //显示最后一项
- db.workmate.find(
- {interest:{$size:3}},
- {name:true,interest:{$slice:-1},age:true,_id:false}
- )
-
- //显示区间项
- //显示从下标为0项到下标为3项
- db.workmate.find(
- {interest:{$size:5}},
- {name:true,interest:{$slice:[0,3]},age:true,_id:false}
- )
十一、MongoDB查询_参数使用方法
- //查询所有,分页显示
- //分页 每页显示两个 年龄从小到大
- //sort 1(从小到大) -1(从大到小)
- db.workmate.find(
- {},
- {name:true,age:true,_id:false}
- ).limit(2).skip(0).sort({age:1})
- //查询age大于30的用户
- //$where
- db.workmate.find(
- {$where:"this.age>30"},//this指代的是workmate集合
- {name:true,age:true,_id:false}
- )
能普通查询尽量不使用$where查询
- 不安全
- 加重了数据库的负担
十二、MongoDB查询_如何在js文本中使用
- //在js中写下如下代码,终端中执行mongo,然后load('当前文件路径.js')就可以执行
- //hasNext()
- var db = connect('company');
- var result = db.workmate.find();//将查到的所有数据赋值给一个变量,最后打印这个变量
-
- //方法一:while
- // while(result.hasNext()){
- // printjson(result.next())
- // }
-
-
- //方法二:forEach()
- result.forEach(function(result){
- printjson(result);
- })
十三、MongoDB索引_构造百万级数据表
首先需要安装node.js环境
- 使用node.js是为了测试随机数和随即用户名是否正确
- 在执行mongo命令,执行load('当前文件路径.js'),运行这段js存储在MongoDB的时候,不能有console.log,mongoShell不支持
- //生成随机数
- function GetRandomNum(min,max){
- let range = max-min;//随机区间 10
- let rand = Math.random();//随机数 0-1
- return (min+Math.round(rand*range));//10+([0-1]*10)
- }
- //console.log(GetRandomNum(10,20))
-
- //生成随机用户名
- function GetRadomUserName(min,max){
- let tempStringArray = "123456789qwertyuiopasdfghjklzxcvbnm".split("");//是个数组
- let outputtext = "";//输出的用户名
- for(let i=1;i<GetRandomNum(min,max);i++){//用户名的长度是一个随机数
- outputtext= outputtext + tempStringArray[GetRandomNum(0,tempStringArray.length-1)]//用户名应该是由tempStringArray数组中的每一项拼成
- }
- return outputtext;
- }
- //console.log(GetRadomUserName(7,16));
-
- //批量插入两百万条数据
- var startTime = (new Date()).getTime();//获取开始时间
- var tempInfo=[];
- for(let i=0;i<2000000;i++){
- tempInfo.push({
- username:GetRadomUserName(7,16),
- regediteTime:new Date(),
- randNum0:GetRandomNum(100000,999999),
- randNum1:GetRandomNum(100000,999999),
- randNum2:GetRandomNum(100000,999999),
- randNum3:GetRandomNum(100000,999999),
- randNum4:GetRandomNum(100000,999999),
- randNum5:GetRandomNum(100000,999999),
- randNum6:GetRandomNum(100000,999999),
- randNum7:GetRandomNum(100000,999999),
- randNum8:GetRandomNum(100000,999999),
- randNum9:GetRandomNum(100000,999999),
- })
- }
-
- var db = connect('company');//连接数据库
- db.randomInfo.drop();//先删除原有的randomInfo库
- db.randomInfo.insert(tempInfo);//然后添加现在的库
- var endTime = (new Date()).getTime() - startTime;//计算耗时
-
- print("[总共耗时]:----------"+endTime+"ms")
由图可见,还是很快的
十四、MongoDB索引_建立索引
- var startTime = (new Date()).getTime();
-
- var db = connect('company');
- var rs = db.randomInfo.find({username:'9wobojo'});//从数据库中任意取到的一个username
-
- rs.forEach(rs => printjson(rs) );//打印当前这个数据
-
- var runTime = new Date().getTime() - startTime;
- print('[demo]:this run time is '+runTime+'ms');
- //普通查询可能需要1000-2000ms的时间
-
-
- //查看索引
- db.randomInfo.getIndexes()
- //数组中有几个对象就有几个索引,mongodb默认有一个id索引,最多支持64个索引
- [
- {
- "v" : 2,
- "key" : {
- "_id" : 1
- },
- "name" : "_id_",
- "ns" : "company.randomInfo"
- }
- ]
-
-
- //建立索引
- db.randomInfo.ensureIndex({username:1})
- //建立索引之后再次查看索引,可以看到有了两个索引
- [
- {
- "v" : 2,
- "key" : {
- "_id" : 1
- },
- "name" : "_id_",
- "ns" : "company.randomInfo"
- },
- {
- "v" : 2,
- "key" : {
- "username" : 1
- },
- "name" : "username_1",
- "ns" : "company.randomInfo"
- }
- ]
-
- //建立索引之后再次查询可能只需要几毫秒
十五、MongoDB索引_复合索引
15.1 复合索引
所谓的复合索引,就是多条索引查询
首先再建一条索引
db.randomInfo.ensureIndex({randNum0:1})
username索引是字符串索引
randNum索引是数字索引
MongoDB根据索引查询的顺序是通过如下查询的
- > db.randomInfo.getIndexes()
-
- [
- {
- "v" : 2,
- "key" : {
- "_id" : 1
- },
- "name" : "_id_",
- "ns" : "company.randomInfo"
- },
- {
- "v" : 2,
- "key" : {
- "username" : 1
- },
- "name" : "username_1",
- "ns" : "company.randomInfo"
- },
- {
- "v" : 2,
- "key" : {
- "randNum0" : 1
- },
- "name" : "randNum0_1",
- "ns" : "company.randomInfo"
- }
- ]
如果想优先使用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集合中插入两条数据
- db.info.insert({contextInfo:"I am a programmer, I love life, love family. Every day after work, I write a diary."})
- 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'})
- //查询全文中有programmer的内容
- db.info.find({$text:{$search:'programmer'}})
-
- //查询全文中有programmer 或 family 或 diary 或 drink的内容
- db.info.find({$text:{$search:'programmer family diary drink'}})
-
- //查询全文中有programmer 或 family 或 diary的内容,但是不查找drink的内容
- db.info.find({$text:{$search:'programmer family diary -drink'}})
-
- //查询全文中有"love PlayGame"或drink的内容
- //如果两个词之间有空格,MongoDB提供了转义符的形式 \" "
- db.info.find({$text:{$search:"\"love PlayGame\" drink"}})
十七、MongoDB用户的创建删除和管理
17.1 创建管理员
mongo服务启动之后,首先需要进入admin数据库
use admin
然后创建管理员
- //创建管理员
- db.createUser({
- user:'jspang',//用户名
- pwd:'123456',//密码
- customData:{//管理员数据
- name:'技术胖',
- email:'web0432@126.com',
- age:18
- },
- roles:[//权限
- {
- role:"readWrite",//拥有读写权限
- db:"company"//对company数据库拥有权限
- },
- 'read'//其他用户拥有只读权限
- ]
- })
-
- //查询存在的管理员
- db.system.users.find()
-
- //删除管理员
- db.system.users.remove({user:'jspang'})
建权
- //管理员账号密码
- db.auth("jspang","123456")
-
- //建权之后启动mongod使用
- mongod --auth
-
- //启用mongo服务时使用
- //mongo -u 用户名 -p 密码 ip:端口/admin
- mongo -u jspang -p 123456 127.0.0.1:27017/admin
-
- //进入数据库
- use company
-
- //查询集合
- show collections
-
- ...
十八、MongoDB数据库的备份和还原
首先开启服务
然后执行备份命令
- mongodump
- --host 127.0.0.1 //ip地址
- --port 27017 //端口
- --out D:/backup //备份存在的目录
- --collection randomInfo //需要备份的集合
- --db company //需要备份的数据库
- --username username //用户名
- --password password //密码
- 例:
- //备份所有数据到D:/backup目录
- mongodump --host 127.0.0.1 --port 27017 --out D:/backup/
恢复命令
- mongorestore
- --host 127.0.0.1 //ip
- --port 27017 //端口
- --username username //用户名
- --password password //密码
- <path to the backup> //备份的路径
-
- 例:
- mongorestore --host 127.0.0.1 --port 27017 D:/backup/
十九、MongoDB数据库的图形化界面
启动图形化界面之前,首先需要启动mongod服务
可以看到MongoDB下的所有数据库,点击数据库可显示集合,点击集合可查看集合中的数据
查询数据
修改数据
创建集合
MongoDB基础教程到此结束,皆根据JSPang的个人博客教程记录的个人笔记。
不积跬步,无以至千里
博主信息:
昵称: | XCoder
网站: | 我的网站
邮箱: | xueshuai_12@163.com
QQ: | 246776020
QQ群: | 1063233592
WeChat: | js_cool_100