学习记录
MongoDB在Windows下的初体验
目录一、MongoDB的安装1.1 MongoDB的下载安装1.2 环境变量的配置1.3 启动Mongo服务1.4 初体验二、MongoDB基本命令2.1 基本命令12.2 基本命令22.2.1 增加数据2.2.2 修改数据2.2.3 删除三、用JavaScript来写命令四、MongoDB插入的批量操作五、MongoDB Updata常...
2020-01-05 07:05:46
299
                <p id="main-toc"><strong>目录</strong></p> 

一、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 增加数据

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/

mongodump -h 127.0.0.1:27017 -d <数据库名> -o <备份路径[需先创建]>

恢复命令

mongorestore
    --host 127.0.0.1        //ip
    --port 27017            //端口
    --username username     //用户名
    --password password     //密码
    <path to the backup>    //备份的路径

例:
//mongod服务需要先启用 c盘根目录下要先有C:\data\db 目录
mongorestore --host 127.0.0.1 --port 27017 D:/backup/

 当使用 mongo 的一些命令提示 “不是内部或外部命令,也不是可运行的程序或批处理文件” 的时候,你可能下载的mongodb不完整,需要 点击这里 下载zip

 解压之后将 bin 目录下的内容复制到 mongodbbin 目录下即可

 

 

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

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

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

 

查询数据

修改数据

创建集合

 

 

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

不积跬步,无以至千里