基本命令
mongo //启动数据库控制台
show dbs //查看数据库
db //查看当前使用的数据库
use <dbName> //使用某个数据库
show collections //查看集合
show users //查看当前库下的用户
db.dropUser('admin') //删除用户
db.updateUser('admin',{pwd:'password'}) //修改用户密码
db.auth('admin','password') //密码认证
mongodb账号权限配置
mongodb数据库角色
1.数据库用户角色:read、readWrite; 2.数据库管理角色:dbAdmin、dbOwner、userAdmin; 3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager; 4.备份恢复角色:backup、restore; 5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、 dbAdminAnyDatabase 6.超级用户角色:root
1、创建超级管理用户
use admin
db.createUser({
user:'admin',
pwd:'123456',
roles:[{role:'root',db:'admin'}]
})
2、修改mongodb数据库配置文件
开启验证
security:
authorization:enabled
或者
#开启用户认证
auth=true
配置文件说明
#数据库数据存放目录
dbpath=/usr/local/mongodb304/data
#数据库日志存放目录
logpath=/usr/local/mongodb304/logs/mongodb.log
#以追加的方式记录日志
logappend = true
#端口号 默认为27017
port=27017
#以后台方式运行进程
fork=true
#开启用户认证
auth=true
#关闭http接口,默认关闭http端口访问
nohttpinterface=true
#mongodb所绑定的ip地址
bind_ip = 127.0.0.1,192.168.1.140
#启用日志文件,默认启用
journal=true
#这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=true
--quiet # 安静输出
--port arg # 指定服务端口号,默认端口27017
--bind_ip arg # 绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP
--logpath arg # 指定MongoDB日志文件,注意是指定文件不是目录
--logappend # 使用追加的方式写日志
--pidfilepath arg # PID File 的完整路径,如果没有设置,则没有PID文件
--keyFile arg # 集群的私钥的完整路径,只对于Replica Set 架构有效
--unixSocketPrefix arg # UNIX域套接字替代目录,(默认为 /tmp)
--fork # 以守护进程的方式运行MongoDB,创建服务器进程
--auth # 启用验证
--cpu # 定期显示CPU的CPU利用率和iowait
--dbpath arg # 指定数据库路径
--diaglog arg # diaglog选项 0=off 1=W 2=R 3=both 7=W+some reads
--directoryperdb # 设置每个数据库将被保存在一个单独的目录
--journal # 启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里
--journalOptions arg # 启用日志诊断选项
--ipv6 # 启用IPv6选项
--jsonp # 允许JSONP形式通过HTTP访问(有安全影响)
--maxConns arg # 最大同时连接数 默认2000
--noauth # 不启用验证
--nohttpinterface # 关闭http接口,默认关闭27018端口访问
--noprealloc # 禁用数据文件预分配(往往影响性能)
--noscripting # 禁用脚本引擎
--notablescan # 不允许表扫描
--nounixsocket # 禁用Unix套接字监听
--nssize arg (=16) # 设置信数据库.ns文件大小(MB)
--objcheck # 在收到客户数据,检查的有效性,
--profile arg # 档案参数 0=off 1=slow, 2=all
--quota # 限制每个数据库的文件数,设置默认为8
--quotaFiles arg # number of files allower per db, requires --quota
--rest # 开启简单的rest API
--repair # 修复所有数据库run repair on all dbs
--repairpath arg # 修复库生成的文件的目录,默认为目录名称dbpath
--slowms arg (=100) # value of slow for profile and console log
--smallfiles # 使用较小的默认文件
--syncdelay arg (=60) # 数据写入磁盘的时间秒数(0=never,不推荐)
--sysinfo # 打印一些诊断系统信息
--upgrade # 如果需要升级数据库 * Replicaton 参数
--------------------------------------------------------------------------------
--fastsync # 从一个dbpath里启用从库复制服务,该dbpath的数据库是主库的快照,可用于快速启用同步
--autoresync # 如果从库与主库同步数据差得多,自动重新同步,
--oplogSize arg # 设置oplog的大小(MB) * 主/从参数
--------------------------------------------------------------------------------
--master # 主库模式
--slave # 从库模式
--source arg # 从库 端口号
--only arg # 指定单一的数据库复制
--slavedelay arg # 设置从库同步主库的延迟时间 * Replica set(副本集)选项:
--------------------------------------------------------------------------------
--replSet arg # 设置副本集名称 * Sharding(分片)选项
--------------------------------------------------------------------------------
--configsvr # 声明这是一个集群的config服务,默认端口27019,默认目录/data/configdb
--shardsvr # 声明这是一个集群的分片,默认端口27018
--noMoveParanoia # 关闭偏执为moveChunk数据保存
3、重启mongodb服务
/usr/local/mongodb/bin/mongod -f /data/mongo/mongodb.cnf
4、用超级管理员账户连接数据库
mongo admin -u 用户名 -p 密码
mongo 192.168.1.200:27017/test -u user -p password
5、创建数据库用户
如: 数据库名称为<water>
use water
db.createUser({
user: "wateradmin",
pwd: "123456",
roles: [ { role: "dbOwner", db: "water" } ]
})
6、node中连接数据库
const url = 'mongodb://admin:123456@localhost:27017/';
mongoose
Mongoose 是在 node.js 异步环境下对 mongodb 进行便捷操作的对象模型工具。Mongoose 是 NodeJS 的驱动,不能作为其他语言的驱动。
1、通过关系型数据库的思想来设计非关系型数据库 2、基于 mongodb 驱动,简化操作
安装
npm install mongoose --save
连接数据库
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
//如果有账户密码需要采用下面的连接方式:
mongoose.connect('mongodb://admin:123456@localhost:27017/water?authSource=admin', { useNewUrlParser: true });
//带连接回调
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true, useUnifiedTopology: true},function(err){});
mongoose的使用
1、定义Schema
数据库中的 Schema,为数据库对象的集合。schema 是 mongoose 里会用到的一种数据模式, 可以理解为表结构的定义;每个 schema 会映射到 mongodb 中的一个 collection,它不具备 操作数据库的能力
var UserSchema=mongoose.Schema({
name: String,
age:Number,
status:Number
})
2、定义数据模型
定义好了 Schema,接下就是生成 Model。model 是由 schema 生成的模型,可以对数据库的 操作。 注意:
mongoose.model 里面可以传入两个参数也可以传入三个参数 mongoose.model(参数 1:模型名称(首字母大写),参数 2:Schema) mongoose.model(参数 1:模型名称(首字母大写),参数 2:Schema,参数 3:数据库集合名 称) 如果传入 2 个参数的话:这个模型会和模型名称相同的复数的数据库建立连接:如通过下面 方法创建模型,那么这个模型将会操作 users 这个集合。 如果传入 3 个参数的话:模型默认操作第三个参数定义的集合名称
var User=mongoose.model('User', UserSchema);
3、增加数据
var u = new User({ //实例化模型 传入增加的数据
name:'lisi2222333',
age:20,
status:true
})
u.save();
4、删除数据
User.deleteOne({ _id: '5b72ada84e284f0acc8d318a' }, function (err) {
if (err) {
console.log(err);
return;
}
// deleted at most one tank document
console.log('成功');
});
5、修改数据
User.updateOne({ name: 'lisi2222' }, { name: '哈哈哈' }, function(err, res) {
if(err){
console.log(err);
return;
}
console.log('成功')
});
6、查找数据
User.find({},function(err,docs){
if(err){
console.log(err);
return;
}
console.log(docs);
})
7、保存成功回显
var u=new User({
name:'lisi2222333',
age:20,
status:true //类型转换
})
u.save(function(err,docs){
if(err){
console.log(err);
return;
}
//console.log(docs);
User.find({},function(err,docs){
if(err){
console.log(err);
return;
}
console.log(docs);
})
});
模式修饰符
预定义修饰符
mongoose 提供的预定义模式修饰符,可以对我们增加的数据进行一些格式化。
lowercase: 转成小写字母
uppercase: 转成大写字母
trim: 去掉两头空格
var UserSchema=mongoose.Schema({
name:{
type:String,
trim:true
},
age:Number,
status:{
type:Number,
default:1
}
})
自定义修饰符
除了 mongoose 内置的修饰符以外,我们还可以通过 set(建议使用) 修饰符在增加数据的 时候对数据进行格式化。也可以通过 get(不建议使用)在 实例获取数据的时候对数据进行 格式化。
var NewsSchema=mongoose.Schema({
title:"string",
author:String,
pic:String,
redirect:{
type:String,
set(url){
if(!url) return url;
if(url.indexOf('http://')!=0 && url.indexOf('https://')!=0){
url = 'http://' + url;
}
return url;
}
},
content:String,
status:{
type:Number,
default:1
}
})
mongoose索引
索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更 快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询 优化技巧。
var DeviceSchema = new mongoose.Schema({
sn: {
type: Number,
// 唯一索引
unique: true
},
name: {
type: String,
// 普通索引
index: true
}
});
扩展CURD方法
var mongoose=require('./db.js');
var UserSchema=mongoose.Schema({
name:{
type:String
},
age:Number,
status:{
type:Number,
default:1
}
})
// 静态方法
UserSchema.statics.findByUid=function(uid,cb){
this.find({"_id":uid},function(err,docs){
cb(err,docs)
})
}
// 实例方法
UserSchema.methods.print = function(){
console.log('这是一个实例方法');
console.log(this);
};
module.exports=mongoose.model('User',UserSchema,'user');
数据校验
内置校验字段
required : 表示这个数据必须传入 max: 用于 Number 类型数据,最大值 min: 用于 Number 类型数据,最小值 enum:用于String类型 枚举类型,要求数据必须满足枚举值 enum: ['0', '1', '2'] match:增加的数据必须符合 match(正则)的规则 maxlength:最大长度 minlength:最小长度
var UserSchema = new mongoose.Schema({
name:{
type:String,
required: true,
},
age: {
type: Number,
// 是否必须的校验器
required: true,
// 数字类型的最大值校验器
max: 120,
// 数字类型的最小值校验器
min: 0
},
status: {
type: String,
// 设置字符串的可选值
enum: ['0', '1', '2']
},
phone:{
type:Number,
match: /^\d{11}$/
},
desc: {
type: String,
maxlength:20,
minlength:10
}
});
自定义校验
在缺省情况下创建的索引均不是唯一索引。下面的示例将创建唯一索引,如:
var UserSchema = new mongoose.Schema({
name:{
type:String,
required: true,
},
age: {
type: Number,
// 是否必须的校验器
required: true,
// 数字类型的最大值校验器
max: 120,
// 数字类型的最小值校验器
min: 0
},
status: {
type: String,
// 设置字符串的可选值
enum: ['0', '1', '2']
},
phone:{
type:Number,
match: /^\d{11}$/
},
desc: {
type: String,
// 自定义的验证器,如果通过验证返回 true,没有通过则返回 false
validate: function(desc) {
return desc.length >= 10;
}
}
});
aggregate 聚合管道
基本使用
MongoDB 中使用 db.COLLECTION_NAME.aggregate([{},...]) 方法来构建和使用聚合管道。先看下官网给的实例,感受一下聚合管道的用法。
db.COLLECTION_NAME.aggregate([{<stage>},...])
db.orders.aggregate([{
$match:{status:'A'}
},{
$group:{_id:"$cust_id",total:{$sum:"$amount"}}
}])
{cust_id:'A123',amount:500,status:'A'}
{cust_id:'A123',amount:250,status:'A'}
{cust_id:'B212',amount:200,status:'A'}
{cust_id:'A123',amount:300,status:'D'}
//$match
{cust_id:'A123',amount:500,status:'A'}
{cust_id:'A123',amount:250,status:'A'}
{cust_id:'B212',amount:200,status:'A'}
//$group
{_id:'A123',total:750}
{_id:'B212',total:200}
管道操作符与表达式
管道操作符
| 管道操作符 | 描述 |
|---|---|
| $project | 增加、删除、重命名字段 |
| $match | 条件匹配。只满足条件的文档才能进入下一阶段 |
| $limit | 限制结果的数量 |
| $skip | 跳过文档的数量 |
| $sort | 条件排序。 |
| $group | 条件组合结果 统计 |
| $lookup | $lookup 操作符 用以引入其它集合的数据 (表关联查询) |
SQL 和 和 NOSQL 对比:
| SQL | NOSQL |
|---|---|
| WHERE | $match |
| GROUP BY | $group |
| HAVING | $match |
| SELECT | $project |
| ORDER BY | $sort |
| LIMIT | $limit |
| SUM() | $sum |
| COUNT() | $sum |
| join | $lookup |
管道表达式
管道操作符作为“键”,所对应的“值”叫做管道表达式。 例如{match:{status:"A"}},match 称为管道操作符,而 status:"A"称为管道表达式, 是管道操作符的操作数(Operand)。 每个管道表达式是一个文档结构,它是由字段名、字段值、和一些表达式操作符组成的。
| 常用表达式操作符 | 描述 |
|---|---|
| $addToSet | 将文档指定字段的值去重 |
| $max | 文档指定字段的最大值 |
| $min | 文档指定字段的最小值 |
| $sum | 文档指定字段求和 |
| $avg | 文档指定字段求平均 |
| $gt | 大于给定值 |
| $lt | 小于给定值 |
| $eq | 等于给定值 |
order集合
{
{"order_id":"1","uid":10,"trade_no":"111","all_price":100,"all_num":2},
{"order_id":"2","uid":7,"trade_no":"222","all_price":90,"all_num":2},
{"order_id":"3","uid":9,"trade_no":"333","all_price":20,"all_num":6}
}
order_item集合
{
{"order_id":"1","title":"商品鼠标 1","price":50,num:1},
{"order_id":"1","title":"商品键盘 2","price":50,num:1},
{"order_id":"1","title":"商品键盘 3","price":0,num:1},
{"order_id":"2","title":"牛奶","price":50,num:1},
{"order_id":"2","title":"酸奶","price":40,num:1},
{"order_id":"3","title":"矿泉水","price":2,num:5},
{"order_id":"3","title":"毛巾","price":10,num:1}
}
$project
修改文档的结构,可以用来重命名、增加或删除文档中的字段。
要求查找 order 只返回文档中 trade_no 和 all_price 字段
db.order.aggregate([{
$project:{ trade_no:1, all_price:1 }
}],function(err,doc))
$match
用于过滤文档。用法类似于 find() 方法中的参数。
db.order.aggregate([{
$project:{ trade_no:1, all_price:1 }
},{
$match:{"all_price":{$gte:90}}
}])
$group
将集合中的文档进行分组,可用于统计结果。统计每个订单的订单数量,按照订单号分组
db.order_item.aggregate([{
$group: {_id: "$order_id", total: {$sum: "$num"}}
}])
$sort
将集合中的文档进行排序。
db.order.aggregate([{
$project:{ trade_no:1, all_price:1 }
},{
$match:{"all_price":{$gte:90}}
},{
$sort:{"all_price":-1}
}])
$limit
db.order.aggregate([{
$project:{ trade_no:1, all_price:1 }
},{
$match:{"all_price":{$gte:90}}
},{
$sort:{"all_price":-1}
},{
$limit:1
}])
$skip
db.order.aggregate([{
$project:{ trade_no:1, all_price:1 }
},{
$match:{"all_price":{$gte:90}}
},{
$sort:{"all_price":-1}
},{
$skip:1
}])
$lookup
db.order.aggregate([{
$lookup:{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
}],function(err,doc){})