mongodb
命令行参数方式启动服务
mongod --dbpath=..\data\db
默认端口号为27017
如果是压缩包(解压后)创建服务(必须通过管理员的权限运行dos命令)
bin/mongod.exe --install --dbpath 路径 --logpath 日志路径
启动
net start mongodb
进入shell交互界面
mongo #不设密码
exit # 退出
权限验证
-
增加数据库的用户验证:
1、添加超级管理员 mongo use admin db.createUser({ "user":"admin", "pwd":"123456", "roles":[{"root","db":"admin"}]}) 2、推出卸载服务 bin下有mongod 执行 mongod --remove (管理员运行) 3、重新安装需要输入账号密码的服务(注意:在原安装命令的基础上添加--auth即可 mongod --install --dbpath=存放data路径 --logpath=存放日志路径\mongodb1.log --auth 主要日志名不能重复 4、启动服务-->登录完成 登录:mongo IP(ip地址):port(端口号)/database(数据库名) -u(用户名) -p(密码)
// db.createUser({ "user":"root", "pwd":"123456", "roles":[{"role":"readWrite","db":"test"}]})
-
执行以上命令以后再进行授权操作
storage:
dbpth:
MongoDB基本操作
基本概念
- 数据库(database)、集合(collection)、数据/文档(document)
数据库的基本语法
- 查看数据库
show databases
- 进入数据库
use 数据库名 //如果数据库存在就隐式创建
db.dropDatabase()
- 查看集合
show collections
- 创建集合
db.createCollection('集合名')
- 删除集合
db.集合名.drop()
数据操作
-
增(集合存在则直接插入数据,集合不存在–隐式创建)
mongodb会给每条数据加上唯一的_id键(是由时间戳,机器,PID,计数器)
//插入单条数据
db.集合名.insert(JSON数据)
db.firstcolrction.insert({uname:"frank",age:18})
//插入多条数据
db.集合名.insert([
{uname:"frank1",age:19},
{uname:"frank2",age:20}
])
// 可以用for循环插入多条数据
for (var i=1; i<=10; i++){
db.集合名.insert({uname:"a"+i,age:i})
}
- 查
db.集合名.find()
db.firstcolrction.find(条件 [查询的列])
// 条件:
查询所有数据: {}或者不写
查询age=19的数据 {age:19}
既查询age=19又要性别=男 {age:6,sex:"男"}
// 查询的列(可选参数)
不写----查询全部字段
{age:1} ----只显示age字段
db.集合名.find({},{age:1})
{age:0} ----除了age字段,其他的都显示
- 运算符
运算符 | 作用 |
---|---|
$gt | 大于 |
$gte | 大于等于 |
$lt | 小于 |
$lte | 小于等于 |
$ne | 不等于 |
$in | in |
$nin | not in |
- 查询中运算符的应用
// 查询年龄大于10的数据
db.集合名.find({age:{$gt:10}})
// 查询年龄在3,8,19岁的数据
db.集合名.find({age:{$in:[3,8,19]}})
- 改
db.集合名.update(条件,新数据 [是否新增,是否修改多条])
// 是否新增:指条件匹配数据数据 true是插入,false否(默认为false)
// 是否修改多条: 指将匹配成功的数据都修改(true是,false否)
// 替换
db.集合名.update({uname:"frank1"},{uname:"frank0"})
//升级语法
db.集合名.update(条件,{修改器:{键:值}})
db.testcol1.update({uname:"frank1"},{$set:{uname:"frank0"}})
// 递增
db.testcol1.update({uname:"frank10"},{$inc:{age:2}})//给frank10 加两岁
// 修改字段 db.testcol2.insert({uname:"zhangwuji",age:22,who:"man",other:"songchaoren",can:"jiuyangshenggong"})
// 将age 加200 uname 改为 zhangshangfeng who 字段改为sex 删除 other 删除 can
db.testcol2.update({uname:"zhangwuji"},{$set:{uname:"zhangshangfong"},$inc:{age:200},$rename:{who:"sex"},$unset:{other:true},$unset:{can:tru
e}})
- 修改运算符
修改器 | 作用 |
---|---|
$inc | 递增 |
$rename | 重命名 |
$set | 修改列值 |
$unset | 删除列 |
- 删
db.集合名.remove(条件,[是否删除一条]) true 删除一条,false删除多条
-
数据库设计
-
集合名称:student
-
字段名称:s_id, s_no, s_name, s_tel, s_sex, s_age, s_gra, s_mark
use school for (var i=1; i<=20; i++){ db.stu.insert({ s_id:i, s_no:"st"+i, s_name:"frank"+i, s_tel:"18286562925", sex:"man", school:"henanchengjianxueyuan", remark:"good man" }) }
-
数据格式化
db.stu.find().pretty()
-
分页&排序
- 排序
db.集合名.find().sort(JSON数据)
// 键--是要排序的字段 值:1 升序,-1降序
// 创建一个集合
for (var i=1;i<=20;i++){
price = i+100;
db.goods.insert({g_no:i,g_price:price,g_name:"goods"+i}
);}
// 按价格进行排序
db.goods.find().sort({g_price:-1}) //降序
db.goods.find().sort({g_price:-1}) //升序
- 分页limit与skip方法
db.集合名.find().sort().skip(数字).limit(数字)
// skip跳过指定数量,limit限定查询数量
db.stu.find().sort({g_price:-1}).skip(0).limit(4) //跳过0条
db.stu.find().sort({g_price:-1}).skip(4).limit(4) //跳过4条
- 聚合查询
// 聚合查询就是把数据聚集起来,然后统计
db.聚合名称.aggregate(
[
{管道:{表达式}}
]
)
- 常用的管道
关键字 | 作用 |
---|---|
$group | 将聚合中的文档分组,用于统计结果 |
$match | 过滤数据,值输出符合条件的文档 |
$sort | 聚合数据进一步排序 |
$skip | 跳过指定文档数 |
$limit | 限制集合数据返回文档数 |
- 常用表达式
关键字 | 作用 |
---|---|
$sum | 总和 $sum:1 同count表示统计 |
$avg | 平均 |
$min | 最小 |
$max | 最大 |
db.human.insert({hname:"frank1",sex:1,age:18})
db.human.insert({hname:"frank2",sex:1,age:19})
db.human.insert({hname:"frank3",sex:1,age:17})
db.human.insert({hname:"frank4",sex:2,age:20})
db.human.insert({hname:"frank5",sex:2,age:21})
db.human.insert({hname:"frank6",sex:2,age:22})
// 1 是男 2 是女
// 统计男生,女生的总年龄
db.human.aggregate(
[
{$group:{_id:"$sex",
result:{$sum:"$age"}
}}
]
)
// 返回结果
{ "_id" : 2, "result" : 63 }
{ "_id" : 1, "result" : 54 }
// 统计男生,女生人数
db.human.aggregate(
[
{
$group:{_id:"$sex",result:{$sum:1}}
}
]
)
// 返回结果
{ "_id" : 1, "result" : 3 }
{ "_id" : 2, "result" : 3 }
// 求人类总数和平均年龄
db.human.aggregate(
[
{$group:{_id:null,
total_num:{$sum:1},
avg_num:{$avg:"$age"}
}}
]
)
// 执行结果
{ "_id" : null, "total_num" : 6, "avg_num" : 19.5 }
// 查询男生,女生人数,按人数升序
db.human.aggregate(
[
{$group:{
_id:"$sex",
result:{$sum:1}
}},
{$sort:{result:1}}
]
)
// 执行结果
{ "_id" : 1, "result" : 3 }
{ "_id" : 2, "result" : 3 }
去重
db.runcommand({“distinct”:“集合名”, “key”:“列名”})
索引
- 索引是一种排序好的便于快速查询的数据结构
- 作用:帮助数据库高效查询数据
- 优点
- 提高数据查询效率,减低数据库的io成本
- 通过索引对数据进行排序,降低数据排序成本,降低cpu的消耗
- 缺点
- 占用磁盘空间
- 大量的索引影响SQL语句的效率,因为每次插入和修改数据都需要更新索引
- 语法
//创建索引
db.集合名.createIndex(待创建索引的列 [,额外选项])
// 参数
待创建索引的列:{键:1,...,键:-1}
1 为升序, -1 为降序
额外选项:设置索引的名称或者唯一索引等等
// 删除索引
db.集合名.dropIndexes() //全部删除
db.集合名.dropIndex(“索引名”) //指定删除
//查看索引
db.集合名.getIndexes()
// 创建十万条数据
use million_datas
//向数据库中插入数据
for (var i=1;i<=100000;i++){
db.md.insert({uname:"md"+i,age:i});
}
// 给name添加普通索引
db.md.createIndex({name:1})
// 返回结果
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
// 查看索引
db.md.getIndexes()
// 返回结果
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "million_datas.md"
},
{
"v" : 2,
"key" : {
"uname" : 1
},
"name" : "uname_1",
"ns" : "million_datas.md"
}
]
// 删除name索引
db.md.dropIndex("uname_1")
// 返回结果
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "million_datas.md"
}
]
给unane 创建索引并取集合名 indexName
db.md.createIndex({uname:1}, {name:"indexName"})
创建组合/复合索引
-
给uname和age添加索引
-
说明:一次性给两个字段添加索引
-
语法:db.集合名.createIndex({键1:方式,键2:方式})
db.md.createIndex({uname:1,age:1})
创建唯一索引
-
给class_字段添加唯一索引
-
语法:db.集合名.createIndex({class_:1},{unique:"class__ "})
db.md.createIndex({class_:1},{unique:"class__ "})
分析索引(explain)
-
语法:db.集合名.find().explain(“executionStats”)
> db.test2col.find().explain("executionStats") { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test2.test2col", "indexFilterSet" : false, "parsedQuery" : { }, "winningPlan" : { "stage" : "COLLSCAN", "direction" : "forward" }, "rejectedPlans" : [ ] }, "executionStats" : { //执行计划统计 "executionSuccess" : true,//执行成功状态 "nReturned" : 1001,//返回结果数码 "executionTimeMillis" : 0,//执行所需时间,毫秒 "totalKeysExamined" : 0,//索引查询时间 "totalDocsExamined" : 1001,//检查文档总数 "executionStages" : { "stage" : "COLLSCAN",//索引扫描方式 "nReturned" : 1001,//返回结果集数目 "executionTimeMillisEstimate" : 0,//估计执行时间,毫秒 "works" : 1003,//工作单元数,一个查询会被派生为一个小工作单元 "advanced" : 1001,//优先返回结果数目 "needTime" : 1, "needYield" : 0, "saveState" : 7, "restoreState" : 7, "isEOF" : 1, "direction" : "forward", "docsExamined" : 1001 } }, "serverInfo" : { "host" : "iZx3egxbt07bbrZ", "port" : 27017, "version" : "4.2.8", "gitVersion" : "43d25964249164d76d5e04dd6cf38f6111e21f5f" }, "ok" : 1
COLLECTION 全表扫描
> db.test2col.find({uname:"frank600"}).explain('executionStats') { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test2.test2col", "indexFilterSet" : false, "parsedQuery" : { "uname" : { "$eq" : "frank600" } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "uname" : 1 }, "indexName" : "indexName", "isMultiKey" : false, "multiKeyPaths" : { "uname" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "uname" : [ "[\"frank600\", \"frank600\"]" ] } } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 10, "totalKeysExamined" : 1, "totalDocsExamined" : 1, "executionStages" : { "stage" : "FETCH", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "docsExamined" : 1, "alreadyHasObj" : 0, "inputStage" : { "stage" : "IXSCAN", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "keyPattern" : { "uname" : 1 }, "indexName" : "indexName", "isMultiKey" : false, "multiKeyPaths" : { "uname" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "uname" : [ "[\"frank600\", \"frank600\"]" ] }, "keysExamined" : 1, "seeks" : 1, "dupsTested" : 0, "dupsDropped" : 0 } } }, "serverInfo" : { "host" : "iZx3egxbt07bbrZ", "port" : 27017, "version" : "4.2.8", "gitVersion" : "43d25964249164d76d5e04dd6cf38f6111e21f5f" }, "ok" : 1 }
FETCH 根据索引去指定扫描
IXSCAN 索引扫描
数据备份
-
语法:mongodump -h -port -u -p -d -o
-
说明:
-h ip地址 -port 端口 -u 用户名 -p 密码 -d 数据库 (不写就默认导出全部) -o 把数据备份到指定目录下
还原数据库
-
语法:mongodump -h -port -u -p -d --drop
-
说明:
-h ip地址 -port 端口 -u 用户名 -p 密码 -d --drop 先删除再还原