MongoDB数据库
一、数据库定义
数据库即存储数据的仓库,可以将数据进行有序的分门别类的存储。它是独立于语言之外的软件,可以通过API去操作它。
常见的数据库软件有:mysql、mongoDB、oracle、sqlserver。
二、MongoDB数据库下载安装
下载地址:https://www.mongodb.com/try/download/community
MongoDB可视化软件
下载地址:https://www.mongodb.com/try/download/compass
MongoDB数据库工具
下载地址:https://www.mongodb.com/try/download/database-tools
三、Mongoose第三方包
使用Node.js操作MongoDB数据库需要依赖Node.js第三方包mongoose。
使用npm install mongoose命令下载。
四、启动MongoDB
在命令行工具中运行net start mongoDB即可启动MongoDB,否则MongoDB将无法连接。
五、导入mongoose和数据库连接
使用mongoose提供的connect方法连接数据库。
注意:如果连接的数据库(MySchool)不存在,会自动创建数据库(MySchool)。
// 导入mongoose
let mongoose = require('mongoose')
// 连接数据库
mongoose.connect('mongodb://localhost/MySchool',
{ useNewUrlParser: true,useUnifiedTopology: true })
.then(() => console.log('数据库连接成功'))
.catch(err => console.log('数据库连接失败', err));
六、创建集合(表)
创建集合分为两步,一是对集合设定规则,二是创建集合,通过mongoose.Schema构造函数的实例即可创建集合。
(1)定义表规则
定义表规则:表里面的有哪些列,分别是什么数据类型。
① 基本写法
// 定义student表规则
const studentSchema = new mongoose.Schema({
//定义具体的表规则
name: String,
age: Number,
sex:String,
hobbies:[String],
isVip: Boolean
});
② 定义表里具体属性的规范
在创建集合规则时,可以设置当前字段的验证规则,验证失败就会插入失败。
required:值为true时不允许为空
minlength:字符串最小长度
maxlength:字符串最大长度
min:最小值
max:最大值
trim:值为true去除字符串两边的空格
validate:自定义验证器
default:默认值
enum: ['html', 'css', 'javascript', 'node.js']
let studentSchema = new mongoose.Schema({
//name属性的规范
name:{
type:String, // 类型是String
require:true, // 不允许为空
minlength:2, // 最小长度为2
maxlength:8 // 最大长度为8
},
sex:{
type:String,
default:'男' // 性别的默认值是“男”
},
age:{
type:Number,
min:3, // 年龄的范围是3-100
max:100
},
hobbies:{
type:[String],
require:false // 爱好允许为空
}
})
(2)创建表对象并应用规则
注意:数据库中的表名会自动改成复数格式(students)
const Student = mongoose.model('Student', studentSchema)
七、创建文档(插入数据)
创建文档实际上就是向集合中插入数据。
方法(1)通过表实例对象
步骤① 创建表实例对象
const stu1 = new Student({
name: '张三',
age: 20,
sex: '男',
hobbies: ['学习','睡觉','打球'],
isVip:true
});
步骤② 调用实例对象的save方法将数据保存到数据库中
stu1.save((err,result)=>{
if(!err){
// 添加成功,打印添加的结果
console.log(result);
}
})
方法(2)create方法,通过回调函数返回结果
通过数据表的create的方法,直接向数据表中添加数据(通过回调函数返回结果)。
Student.create({
name: '李四',
age: 22,
sex: '女',
hobbies: ['看电视','睡觉','看电影'],
isVip:false
},(err,result)=>{
if(!err){
console.log(result);
}
})
方法(3)create方法,通过Promise对象返回结果
通过数据表的create的方法,直接向数据表中添加数据(通过Promise对象返回结果)。
Student.create({
name: '王五',
age: 24,
sex: '男',
hobbies: ['敲代码','睡觉','写字'],
isVip:true
}).then(result=>{
console.log(result);
}).catch(err=>{
console.log(err);
})
八、查询数据
(1)查询全部信息 find()
find方法返回的是数组。
// 查询student表的全部数据
Student.find().then(r=>{
console.log(r);
})
(2)根据条件查询 find(条件)
返回的是符合条件的数组。如果没有满足条件的结果,就返回一个空数组。
Student.find({name:'李白'}).then(r=>{
console.log(r);
})
(3)返回表中的第一个对象 findOne()
findOne方法返回的是对象。
Student.findOne().then(r=>{
console.log(r);
})
(4)根据条件查询 findOne(条件)
查询第一个满足条件的,返回的是对象,如果没有满足条件的结果,就返回null。
Student.findOne({name:'李白'}).then(r=>{
console.log(r);
})
(5)查询某个范围内的数据
① 查询大于某数值的数据 $gt
// 查询年龄大于20岁的学生信息
Student.find({age:{$gt:20}}).then(r=>{
console.log(r);
})
② 查询大于某数值的数据 $lt
// 查询年龄小于20岁的学生信息
Student.find({age:{$lt:20}}).then(r=>{
console.log(r);
})
③ 查询两数之间的数据 {$gt:num1,$lt:num2}}
// 查询年龄在20岁到40岁之间的学生信息
Student.find({age:{$gt:20,$lt:40}}).then(r=>{
console.log(r);
})
④ 查询两数之间的数据(包括两数) {$gte:num1,$lte:num2}}
// 查询年龄在20岁到40岁之间的学生信息(包括20和40)
Student.find({age:{$gte:20,$lte:40}}).then(r=>{
console.log(r);
})
(6)根据正则表达式匹配查询条件(用于模糊查询)
$regex 正则,用于模糊查询。
select方法,筛选查询列。注意:_id列默认会返回,如果不需要查询id,就加上-_id。
// 查询姓名中包含'刘'的学生信息,只返回name、sex、age列
Student.find({name:{$regex:/刘/i}}).select('name sex age -_id').then(r=>{
console.log(r);
})
注意:如果正则条件是模板字符串,需要使用new RegExp()创建。
Student.find({ name: { $regex: new RegExp(`${name}`, 'i') } }).then(r => {res.send(r)})
(7)匹配包含
① $in 满足其中一个元素的数据
// 查询爱好中包含‘睡觉’或‘学习’的学生信息
Student.find({hobbies:{$in:['睡觉','学习']}}).select('name sex age hobbies -_id').then(r=>{
console.log(r);
})
② $all 满足所有元素的数据
// 查询爱好中包含‘睡觉’和‘学习’的学生信息
Student.find({hobbies:{$all:['睡觉','学习']}}).select('name sex age hobbies -_id').then(r=>{
console.log(r);
})
(8)对查询结果排序 sort()
① 升序排列
// 根据年龄升序查询学生信息
Student.find().sort('age').select('name sex age -_id').then(r=>{
console.log(r);
})
② 降序排列
// 根据年龄降序查询学生信息
Student.find().sort('-age').select('name sex age -_id').then(r=>{
console.log(r);
})
③ 根据性别升序,再根据年龄降序
// 先返回相同性别的学生,相同性别的学生再根据年龄降序
Student.find().sort('sex -age').select('name sex age -_id').then(r=>{
console.log(r);
})
(9)分页查询
skip()跳过多少条数据;limit()限制查询数量。
// 每页2条数据,显示第2页
let pageIndex = 2 //定义页码
let pageSize = 2 //定义每页数量
Student.find().skip((pageIndex-1)*pageSize).limit(pageSize).select('name sex age -_id').then(r=>{
console.log(r);
})
九、更新数据
(1)更新单个 updateOne()
updateOne({查询条件}, {要修改的值})
Student.updateOne({_id:'617f5d951df9a826303015fa'},{name:'张飞',age:38}).then(r=>{
console.log(r);
})
(2)更新多个 updateMany()
updateMany({查询条件}, {要更改的值})
Student.updateMany({sex:'女'},{age:25}).then(r=>{
console.log(r);
})
十、删除数据
(1)删除单个 findOneAndDelete()
删除成功后,返回删除的对象。
Student.findOneAndDelete({ _id: '617f5d951df9a826303015fa' }).then(r => {
console.log(r)
})
(2)删除单个 deleteOne()
删除成功后,返回删除的数量。
Student.deleteOne({ _id: '617f5d951df9a826303015fc' }).then(r => {
console.log(r)
})
(3)删除多个 deleteMany()
删除成功后,返回删除的数量。
Student.deleteMany({sex:'女'}).then(r=>{
console.log(r);
})
十一、集合关联
通常不同集合的数据之间是有关系的,例如文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联。
(1)使用id对集合进行关联
(2)使用populate方法进行关联集合查询
// 用户集合
const User = mongoose.model('User', new mongoose.Schema({ name: { type: String } }));
// 文章集合
const Post = mongoose.model('Post', new mongoose.Schema({
title: { type: String },
// 使用ID将文章集合和作者集合进行关联
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}));
// 联合查询
Post.find()
.populate('author')
.then((err, result) => console.log(result));