MongoDB简介
基本概念
-
MongoDB是一个基于分布式文件存储的开源数据库系统。旨在为WEB应用提供可扩展的高性能数据存储解决方案,是前端开发的必备工具之一。MongoDB是一种非关系型数据库,也叫文档型数据库。不支持SQL查询语句,属于新兴数据库范畴。
-
database:数据库
document:文档,是一条具体的数据,相当于JS中的对象(表中一行)
field:字段,文档中属性的名称,相当于JS对象属性
collection:集合(一张表)
MongoDB的优劣
-
优势:
- 在适量级的内存的MongoDB的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据的读写变得十分快。
- MongoDB的高可用和集群架构拥有十分高的扩展性。
- MongoDB的Bson和JSon格式的数据十分适合文档格式的存储与查询。
-
劣势:
- 不支持事务操作。MongoDB本身没有自带事务机制,若需要在MongoDB中实现事务机制,需通过一个额外的表,从逻辑上自行实现事务。
- 应用经验少,由于NoSQL兴起时间短,应用经验相比关系型数据库较少。
- MongoDB占用空间比起MySQL较大。
MongoDB的下载和配置
-
下载:点击前往官网下载
-
配置的话由于有可能会遇到各种各样的错误,花费了我很长时间,所以我的建议是点击跳转配置文章,这是我在网上看见的最为详细的配置教程,建议跟着这篇文章进行配置。
-
个人小建议
-
最好不要使用默认路径存储到C盘的Program File文件夹下,需要操作权限较为麻烦。
-
如果在配置是路径中有空格,那么一定要在路径上加上双引号,否则会解析成两个路径
-
环境变量记得添加
-
-
启动和停止MongoDB
- net start mongoDB
- net stop mongoDB
Mongoose第三方包
基本概念
- Mongoose是Node.js操作MongoDB数据库所必须要依赖的第三方包,利用Mongoose里面设置好的API实现对数据库的连接以及对数据库集合的创建。
- 下载:在Node.js命令行输入npm install mongoose
数据库连接
//引入第三方模块
const mongoose = require('mongoose');
//设置为true则使Mongoose的默认索引构建使用createIndex()而不是ensureIndex()
//以避免来自MongoDB驱动程序的弃用警告
mongoose.set('useCreateIndex', true);
//连接数据库
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true }) //如果没有这个数据库会自动帮我们创建这个数据库,playground是数据库名
.then(() => console.log('数据库连接成功')) //捕捉创建结果
.catch(err => console.log('数据库连接失败', err))
在power shell命令行中执行该js文件即可实现对数据库的连接操作
创建集合
分为两步一是对集合设定规则;二是创建集合
const courseSchema = new mongoose.Schema({ //创建集合规则
name: String,
author: String,
isPublished: Boolean
}); //创建了集合的规则名为courseSchema
const Course = mongoose.model('Course', courseSchema); //应用规则来创建集合,创建了一个名为course的集合,注意model方法返回的是当前集合的构造函数,第一个参数为集合名称,第二个参数为运用的规则
MongoDB的增删改查(Node.js环境)
创建文档
- 创建文档实际上就是对集合中插入数据也就是“增”的操作
- 同样分为两步
- 创建集合实例
- 调用实例对象下的save方法
//通过实例对象的方法
const db = new Course({ //在集合中写入数据
name: 'html',
author: '小齐',
isPublished: true
})//db就是我们插入的数据也就是一条文档
db.save();//保存,实现插入
-
还有一种创建文档的方法
利用集合中的create方法,返回的也是promise对象
Course.create({
name:'javascript',
author:'小方',
isPublished:true
},(err,doc)=>{
console.log(err);
console.log(doc)})
//由于该种方法返回的是promise对象,因此可以用then和catch方法得到结果
删除文档
-
删除单个文档
db.findOneAndDelect({要查询的条件}).then(result=>console.log(result)) //db是一个集合名
-
删除多个文档
db.delectMany({}).then(result=>{console.log(result)}) //db是一个集合名
-
示例代码
// 引入mongoose第三方模块 用来操作数据库
const mongoose = require('mongoose');
// 数据库连接
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true})
// 连接成功
.then(() => console.log('数据库连接成功'))
// 连接失败
.catch(err => console.log(err, '数据库连接失败'));
// 创建集合规则
const userSchema = new mongoose.Schema({
name: String,
age: Number,
email: String,
password: String,
hobbies: [String]
});
// 使用规则创建集合
const User = mongoose.model('User', userSchema);
// 查找到一条文档并且删除
// 返回删除的文档
// 如何查询条件匹配了多个文档 那么将会删除第一个匹配的文档
User.findOneAndDelete({_id: '5c09f267aeb04b22f8460968'}).then(result => console.log(result))
// 删除多条文档
User.deleteMany({}).then(result => console.log(result))
更新(修改)文档
-
更新一条文档
db.updateOne({查询条件},{要修改的值}).then(result=>console.log(result))
-
更新多条文档
db.updateMany({查询条件},{要修改的值}).then(result=>console.log(result)) //在这里当查询条件为空时是全部修改
-
示例代码
// 引入mongoose第三方模块 用来操作数据库
const mongoose = require('mongoose');
// 数据库连接
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true})
// 连接成功
.then(() => console.log('数据库连接成功'))
// 连接失败
.catch(err => console.log(err, '数据库连接失败'));
// 创建集合规则
const userSchema = new mongoose.Schema({
name: String,
age: Number,
email: String,
password: String,
hobbies: [String]
});
// 使用规则创建集合
const User = mongoose.model('User', userSchema);
// 找到要删除的文档并且删除
// 返回是否删除成功的对象
// 如果匹配了多条文档, 只会删除匹配成功的第一条文档
//把名字为李四的文档改为年龄为12,并且名字叫李狗蛋
User.updateOne({name: '李四'}, {age: 12, name: '李狗蛋'}).then(result => console.log(result))
// 把所有的文档的年纪改为30
User.updateMany({}, {age: 30}).then(result => console.log(result))
查询文档
-
查询语法
-
查询一条文档
集合.findOne({查询条件}).then(result=>console.log(result))
-
查询全部文档
集合.find().then(result=>console.log(result))
-
-
匹配大于、小于、包含
$gt:大于
$lt:小于
$in:包含
User.find({age:{$gt:20,$lt:50}}).then(result=>console.log(result)) //匹配User查询大于20小于50的所有用户 User.find({hobbies:{$in:['吃饭']}}).then(result=>console.log(result)) //匹配查询爱好中包含吃饭的所有用户
-
模糊匹配
users.find({name:{$regex:'明'}}); //查询出包含有明字的文档 users.find({name:{$regex:'小'}}); //查询出包含有小字的文档
-
选择想要查询的字段
select('要查询的字段');不想查询到的只要在字段前面加上-即可
集合.find().select('name email -_id').then(result =>console.log(result)) //在集合中查询出name和email字段,不查询id字段
-
跳过和限制查询文档
-
跳过查询文档:skip(n):表示跳过两条数据文档
-
限制查询文档:limit(m):表示限制查询两条用户文档
// 查询文档跳过前两条结果 限制显示3条结果 User.find().skip(2).limit(3).then(result => console.log(result))
-
-
查询结果排序
-
利用sort()方法实现,参数为字段,默认是升序,当在字段前加上-号就会变成降序
-
sort()方法中的参数还可以是对象的形式:{key:排序方式},key表字段,正数代表升序,负数代表降序
-
-
查询文档的数量
集合.find().count().then(result=>console.log(result)) //查询集合中文档的数量
-
集合关联
通常不同的集合的数据之间是有关系的,文章信息和用户信息就在不同的集合中,但文章是用户发布的,要查询文章信息就要访问到用户信息集合,这就是集合关联
在mongoose中提供了populate方法实现集合关联// 用户集合规则 const userSchema = new mongoose.Schema({ name: { type: String, required: true } }); // 文章集合规则 const postSchema = new mongoose.Schema({ title: { type: String }, author: { type: mongoose.Schema.Types.ObjectId,//使用id将集合进行关联 ref: 'User'//写上要关联的集合 } }); // 用户集合 const User = mongoose.model('User', userSchema); // 文章集合 const Post = mongoose.model('Post', postSchema); // 创建用户 User.create({name: 'Kawhi'}).then(result => console.log(result)); // 创建文章 Post.create({titile: '123', author: '5c0caae2c4e4081c28439791'}).then(result => console.log(result)); //将User集合中的author信息关联过来 Post.find().populate('author').then(result => console.log(result))
mongoose验证
基本概念
在创建集合规则时,可以设置当前字段的验证规则,验证失败则输出插入失败
验证的关键字
- required:必传参数;意思是必须写入数据不能为空
- type:文本类型;必选字段
- minlength:字符串的最小长度
- maxlength:字符串的最大长度
- trim:去除字符串两边的空格
- default:设置当前的默认值(创建的时候不用写对象有了default就会默认生成)
- enum:用户只能输入enum里面的内容输入其他的会报错
- max/min:设置数值的最大最小值
自定义验证规则
可以采用validate:自定义验证器的方法实现,具体可见示例代码
错误信息的获取
错误信息都自动存在了error对象里的errors中,可以通过循环取到每一个错误信息
示例代码:
const postSchema = new mongoose.Schema({
title: {
type: String,
required: [true, '请传入文章标题'],
minlength: [2, '文章长度不能小于2'],// 字符串的最小长度
maxlength: [5, '文章长度最大不能超过5'],// 字符串的最大长度
trim: true// 去除字符串两边的空格
},
age: {
type: Number,
min: 18,// 数字的最小范围
max: 100// 数字的最大范围
},
category: {
type: String,
enum: {// 枚举 列举出当前字段可以拥有的值
values: ['html', 'css', 'javascript', 'node.js'],
message: '分类名称要在一定的范围内才可以'
}
},
author: {
type: String,
validate: {
validator: v => {
// 返回布尔值
// true 验证成功
// false 验证失败
// v 要验证的值
return v && v.length > 4
},
// 自定义错误信息
message: '传入的值不符合验证规则'
}
}
});
const Post = mongoose.model('Post', postSchema);
Post.create({title:'aa', age: 60, category: 'java', author: 'bd'})
.then(result => console.log(result))
.catch(error => {
// 获取错误信息对象
const err = error.errors;
// 循环错误信息对象
for (var attr in err) {
// 将错误信息打印到控制台中
console.log(err[attr]['message']);
}
})
网友评论