mongodb常用指令
PS:本笔记的测试数据库为 spa 数据库
♥管理员账号:admin
♥管理员密码:shipingan0818
♥在cmd中连接mongodb数据库:mongo admin -u admin -p shipingan0818
♥在navcat中建立连接:使用password验证
账户管理
mongodb数据库所有角色
1.数据库用户角色:read、readWrite;
2数据库管理角色:dbAdmin、dbOwner、userAdmin
3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4.备份恢复角色: backup、 restore;
5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatebase、dbAdminAnyDatabase
6.超级用户角色。root(权限最高的存在)
提示:root为最高权限数据库,root权限的账号需在系统自带的admin数据库中创建,而dbOwner为对单个数据库有最高权限的账号,需进入其对应数据库创建账号
1.创建超级管理员
use admin
db.createUser({
user:"admin",
pwd:"shipingan0818",
roles:[{role:"root",db:"admin"}]
})
2.修改mongodb安装目录的bin目录下的mongod.cfg配置文件
-
如果要开启远程连接,需要配置为如下信息,注意:在centos服务器中,配置如下信息会报错,具体错误可以到时候再百度
net: #端口号 port: 27017 #ip地址 bindIp: 0.0.0.0
-
# 开启安全认证: security: authorization: enabled
-
db.createUser({ user: 'admin', // 用户名 pwd: 'shipingan0818', // 密码 roles:[{ role: 'root', // 角色权限级别 db: 'admin' // 要管理的数据库 }] })
3.重启mongodb的服务
打开管理器,找到mongodb服务,右键点击重启
4.重新连接数据库
-
在cmd中连接mongodb数据库:mongo admin -u admin -p shipingan0818
-
在navcat中建立连接:使用password验证
-
在项目中的mongoose中:
mongoose.connect('mongodb://admin:shipingan0818@192.168.43.169:27017/wxnews?authSource=admin',{ auto_reconnect: true, useUnifiedTopology: true, useNewUrlParser: true },function (err) { if(err){ console.log('数据库连接失败!'); console.log(err); return; }else{ console.log('数据库连接成功!'); } });
1.创建只对某一个数据库,有所有权限的账号
先进入需要被管理的数据库(比如这个账号要管理eggcms数据库,则需执行 use eggcms 进入数据库)
use eggcms
db.createUser({
user: 'bosszhiju', // 用户名
pwd: '123456', // 密码
roles:[{ //权限配置
role: 'dbOwner', // 角色的权限级别
db: 'bosszhiju' // 要管理的数据库
}]
})
2.使用新创建的账号登录就可以了
mongo eggcms -u eggcms -p 123456
删除用户
db.dropUser(“用户名”)
修改用户密码
db.updateUser(“用户名”,{pwd:“新密码”});
数据库基本操作
0.连接数据库命令: mongo 要操作的数据库名 -u 登录用户名 -p 登录密码
-
use {数据库名} = 创建或者进入一个数据库,注意如果创建数据库,则必须插入一条数据才能成功创建,否则无效
-
show dbs = 显示所有的数据库
-
db.dropDatabase() = 删除当前所在的(就是打开的嘛)数据库
-
db.{集合名}.insert({“name”:“zhangsan”}) = 向集合当中插入一条数据
-
show collections = 显示当前数据库下的所有集合
-
db.{集合名/表名}.drop() = 删除某一个集合
查(find)
普通查询
再普通不过了
- db.{集合名}.find() = 查找某个集合下的所有数据,你为啥知道是所有数据?因为它没传入条件啊
- db.{集合名}.find({“username”:“张三”,“age”:18}) = 查找 username为张三 并且 age为18 的数据
条件查询
在某个区间查找:
-
gt:大于,gt:大于,gt:大于,lt:小于
-
gte:大于等于,gte:大于等于,gte:大于等于,lte:小于等于
-
{gte:参数,gte:参数,gte:参数,lte:参数}:大于等于多少并且小于等于多少
-
db.{集合名}.find({“字段名”:{KaTeX parse error: Expected 'EOF', got '}' at position 6: gt:参数}̲}) = 查询值大于{字段名}…gt改成lt则为小于,lt则为小于,lt则为小于,gt或$lt后面加个e则表示大于等于,或者小于等于
-
db.{集合名}.find({“字段名”:{gt:参数,gt:参数,gt:参数,lt:参数}}) = 查询值大于gt参数并且小于lt参数的数据
模糊查找
查找以什么开头,以什么结尾,包含什么啊这种,语法类似于js的正则表达式规则
- /参数/:包含什么
- /^参数/:以什么开头
- /参数$/:以什么结尾
-
db.user.find({“username”:/六/}) = 查询username中包含 六 的数据
-
db.user.find({“username”:/^六/})) = 查询username中以 六 开头的数据
-
db.user.find({“username”:/是$/}) = 查询username中以 六 结尾的数据
设置查找返回字段
有时候,我们只需要一条数据中的某几个字段,并不需要这些数据的全部字段,这时候我们可以控制返回的数据需要显示哪些字段(需要返回哪些字段)
- db.user.find({“age”:{$gte:20}},{“username”:1,[其它字段]}) = 查找age大于等于20的数据,并且返回值只显示username字段
排序(sort)
不解释,很重要
- db.user.find({“age”:{$gt:23}}).sort({age:1}) = 查找age大于23的数据,并且根据age对数据进行排序 值为1表示升序,值为-1表示降序
统计数据的条数(count)
可以查看数据有多少条
- db.user.find().count()
返回前N条数据(limit)
有时候,我们只需要前n条数据,这时候就能用到这一部分内容了,比如在做排行榜的时候,和分页的时候
注意:参数为 整数
-
db.user.find().limit(4) = 查找数据,只返回4条
-
db.user.find().skip(3) = 查找数据,跳过前面3条
-
db.user.find().skip(5).limit(1) = 查找数据 跳过前面的5条,且只返回1条
当数据过多时(大于20条的时候),我们可以通过 it 来查看下一页 有提示的哦
跳过前n条数据(skip)
db.user.skip(n): n 表示要跳过的条数
例:
db.user.find().skip(3) = 查找数据,跳过前面3条
实现分页功能♥
核心思想就是通过skip()跳过前面的数据,然后返回limit()指定条数的数据
limit=pageSize=每页的条数
skip = 当前第几页-1*pageSize = 需要跳过的条数
或查询(or)
或语句查询,应该也挺好用的吧!
- db.user.find({$or:[{“username”:“王五”},{“username”:“李四”}]}) = 查询username为王五,或者username为李四的数据
改(update)
根据条件修改,修修改改,又一年
♥不加$set的话就是把name为张三的那些数据,替换掉第二个参数的数据
单个修改:
- db.user.update({“name”:“张三”},{$set:{“name”:“张年”,[多个值]}}) = 更改名字为张三的数据,把name改为张年,后面可以跟其它字段,从而实现一次更新多个字段
批量修改:
- db.user.update({“age”:18},{$set:{“sex”:“女”}},{multi:true}) = 查找age为18的数据,并把查找到的数据的sex字段全部更新为 女
修改字段名:
- db.集合名称.update({}, {$rename:{“旧键名称”:“新键名称”}}, false, true) = 修改字段名称
删(remove)
删除很简单,总结就是根据条件删
- db.user.remove({“name”:“张年”}) = 删除name为张年的数据,只要条件符合,能删除多条,如果条件为空,那么会删除user下的所有数据
只删除一条数据
- db.admin.remove({“age”:{$lte:20}},{justOne:true}) = 删除age小于等于20的数据,但是有justOne:true属性后只会删除一条,而不管有多少数据符合删除的条件
索引
为集合创建索引
当传入多个字段时,是为设置复合索引
db.user.ensureIndex({“username”:1}) = 为user集合的username字段创建一个索引,索引值为1(-1也行,表示升降序)
获取当前集合的索引
db.user.getIndexes() = 获取user集合的所有索引
删除当前集合的索引
db.user.dropIndex({“username”:1}) = 删除user集合中username字段的索引
创建唯一索引
db.user.ensureIndex({“usernmae”:1},{“unique”:true}) = 当unique设置为true时,user集合的username字段的值就不能再重复了
aggregate(聚合管道)查询
部分管道操作符:
管道操作符 | 说明 |
---|---|
$project | 增加、删除、重命名字段♥ |
$match | 条件匹配,只满足条件的文档才能进入下一阶段♥ |
$limit | 限制查询结果的数量 |
$skip | 跳过查询的数量 |
$sort | 条件排序 |
$group | 按条件对查询的结果进行 分组 或 统计 |
$lookup | 实现表(集合)的关联查询♥ |
$project(指定字段)
-
返回指定的字段:
db.user.aggregate([{$project:{“username”:1,“age”:1}}])
= 查询user集合,并指定只返回username和age,需要几个就写几个字段
-
对字段进行别名操作:
db.user.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: project:{name:"username"}}])
= 查询user集合,并把集合的username字段别名为name返回,并不会修改原本集合中的字段名,find并不能对返回值进行别名操作哦,所以只能使用聚合管道操作
$match(筛选)
-
db.user.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{"age":{gt:24}}}])
= 查找age大于24的数据
limit和limit和limit和skip
-
db.user.aggregate([{KaTeX parse error: Expected 'EOF', got '}' at position 7: skip:1}̲,{limit:3}])
= 查找user集合,查找后跳过一条,并且限制返回的数据条数为3条
$sort(排序)
-
db.user.aggregate([{$sort:{“age”:1}}])
= 对user集合的数据根据age进行升序排序(-1的话为降序)
$gorup(分组)
说明:
1. _id :强制必须存在。可以为 null
2. 后面跟要显示的其它字段,可以用其它的操作符(sum,sum,sum,avg,avg,avg,max,min,min,min,first,$last)
- $group虽然很好用,但是它是无序的,所以它会很耗内存,不能支持同时处理大量的数据
实际演示:
-
db.user.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup:{**_id:**"sex",number:{sum:"sum:"sum:"age"}}}])
= 按sex进行分组,并分别求出各自的总age数,各自的总age数用number表示
-
db.user.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"sex",number:{$sum:1}}}])
= 按sex进行分组,并求出各自分组的总数,这个查询很有用哦!♥
$lookup(关联查询)
db.order_item.aggregate([
{$lookup:{
from:"order",
localField:"order_id",
foreignField:"order_id",
as:"info"
}
}
])
在order_item表中查询,通过$lookup实现关联查询,其中
from:你要关联的表名
localField:通过order_item表中的order_id字段关联
foreignField:关联order表中的order_id字段
as:order表查询出来的数据,放在info数组里面,没错返回的数据为数组格式
mongoose的使用
下载
npm i mongoose --save
连接
const mongoose = require('mongoose');
//authSource的值为 数据库名或当前验证登录的用户名
mongoose.connect('mongodb://admin:shipingan0818@192.168.43.169:27017/wxnews?authSource=admin',{
auto_reconnect: true,
useUnifiedTopology: true,
useNewUrlParser: true
},function (err) {
if(err){
console.log('数据库连接失败!');
console.log(err);
return;
}else{
console.log('数据库连接成功!');
}
});
定义Schema
Shema:
1.用来统一数据库的数据类型,防止多种操作后数据类型不一致导致产生bug
2.Shema里定义的字段要和数据库中的集合的字段对应起来
const UserSchema = mongoose.Schema({
username:String,
age:Number
});
3.在Scema中指定默认参数,使用default指定,不过此时每个字段的限制就会变成一个对象
const UserSchema = mongoose.Schema({
username:String,
age:{
type:Number,
default:18
}
});
4.在schema中使用预定义模式修饰符,常见的有: lowercase、uppercase、trim
const UserSchema = mongoose.Schema({
username:String,
age:{
type:Number,
default:18
trim:true //去除前后空格
}
});
5.自定义修饰符
const UserSchema = mongoose.Schema({
username:String,
age:{
type:Number,
default:18
}
get(params){
//对需要存入数据库的数据进行处理
let newParams = //处理....
return newParams
}
});
6.设置唯一索引(unique)和普通索引(index)
const UserSchema = mongoose.Schema({
username:{
type:String,
index:true //普通索引
},
age:{
type:Number,
default:18,
trim:true, //去除前后空格
unique:true //唯一索引
}
});
7.在Schema中校验参数,常用的如下表
key | value |
---|---|
required | 表示这个数据必须传入 |
max | 用于Number类型数据,最大值 |
min | 用于Number类型数据,最小值 |
enum | 枚举类型,要求数据必须满足枚举值enum: [‘0’ , ‘1’,‘2’] |
match | 增加的数据必须符合match(正则)的规则 |
maxlength | 最大长度 |
minlength | 最小长度 |
创建Model
model:
1.const UserModel = mongoose.model(‘表名(首字母大写)’,Scema,‘表名(数据库中是啥,这里就写啥)’);
2.第一个参数是数据库中的集合名,首字母必须大写,第二个参数为集合对应的Shema,第三个参数为数据库中的集合名
const UserModel = mongoose.model('User',UserScema,'user');
使用(查)
1.第一个参数控制,要具体如何操作数据库
2.第二个参数为,操作完数据库后返回的结果
//查询
UserModel.find({},function(err,doc){
//处理错误
if(err){
console.log(err);
return;
}
//打印数据
console.log(doc);
});
增加
1.增加数据,需要实例化UserModel
2.然后通过实例化后的对象,调用save方法把数据保存到数据库
let u = new UserModel({
username:'hhh',
age:18
});
u.save(function(err){
if(err){
console.log(err);
return;
}
console.log('添加成功!');
});
更新
1.以下方法差不多,都适用
update
updateOne
findOneAndUpdate
2.Model.update(condition,doc,[options],[callback]);
参数condition:更新的条件,要求是一个对象。
参数doc:要更新的内容,要求是一个对象。
参数[options]:可选参数,要求也是一个对象。
参数[callback]:可选参数,要求是一个回调函数。
[options]有效值:
safe :(布尔型)安全模式(默认为架构中设置的值(true))
upsert :(boolean)如果不匹配,是否创建文档(false)
multi :(boolean)是否应该更新多个文档(false)
runValidators:如果为true,则在此命令上运行更新验证程序。更新验证器根据模型的模式验证更新操作。
setDefaultsOnInsert:如果这upsert是真的,如果创建了新文档,猫鼬将应用模型模式中指定的默认值。该选项仅适用于MongoDB> = 2.4,因为它依赖于MongoDB的$setOnInsert操作符。
strict:(布尔)覆盖strict此更新的选项
overwrite: (布尔)禁用只更新模式,允许您覆盖文档(false)
3.作用:该方法是根据condition这个条件去更新doc这个对象。
例子:
//匹配年龄大于18岁的那条数据,更新它的oldEnough值为true
UserModel.update({usernmae:'hhh'}, {username:'xixixi'},function(err,result){
if(err){
console.log(err);
return;
}
console.log('更新成功!');
});
//如果加了{ multi: true } 则表示把所有 username为hhh的文档的username都修改为xixixi,其实就是一次修改多个结果,如果有的话
UserModel.update({usernmae:'hhh'}, {username:'xixixi'}, { multi: true }, function (err, raw) {
if (err) return handleError(err);
console.log('The raw response from Mongo was ', raw);
});
-
小知识点
$inc:用来增加指定字段的数量
示例:{$inc:{total:1}}
解释:将查找到的所有数据的total字段的值都增加 1
注意事项:
- 若输入的字段不存在,$inc则会创建该字段
- 若把$inc用在了空字段会报错。
联想到:$set会有用吗?
删除
UserModel.delectOne({username:'hhh'},function(err,result){
if(err){
console.log(err);
return;
}
console.log('删除成功!');
});
获取mongoose中获取mongodb的id
通过 mongoose.Schema.Types.objectId(‘id值’) 来获取
操作数组里面的子文档
$addToSet 可以给嵌套结构中文档的array中添加对象
$pull则是删除