mongodb的基本使用

145 阅读9分钟

基本命令

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 对比:

SQLNOSQL
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){})