专业课上,老师经常告诉我们,数据库的操作无非就是增删查改,即CURD,事实也正是如此,我们接下来看看mongoose操作no SQL数据库MongoDB的CURD。

1.连接数据库

连接数据的详细文档请移步mongoose文档

then回调模式

假设数据库连接地址为mongodb://localhost:27017/TestDB

假设数据操作模型Model为:

1
2
3
4
5
6
7
8
9
10
11
12
13
// peopleModel.js
let mongoose = require('mongoose');

let Schema = mongoose.Schema;

let PeopleSchema = new Schema({
name: String,
age: Number,
sex: Number,
class: String
});

module.exports = mongoose.model('People', PeopleSchema, 'peopleCollection');
1
2
3
4
5
6
7
8
9
10
11
const mongoose = require("mongoose");

var mongourl = 'mongodb://localhost:27017/TestDB';
mongoose.connect(mongourl).then(
() => {
console.log('连接成功!')
},
err => {
console.log('出错!', err);
}
);

on监听模式

1
2
3
4
5
6
7
8
9
10
let mongoose = require('mongoose');

let mongoURL = 'mongodb://localhost:27017/TestDB';
mongoose.connect(mongoURL);
mongoose.Promise = global.Promise;
let db = mongoose.connection;
db.on('error',console.error.bind(console, 'MongoDB connection error:'));
db.once('open', function() {
// we're connected!
});

常见操作条件和API

常见的查询条件

  • $or 或关系
  • $nor 或关系取反
  • $gt 大于
  • $gte 大于等于
  • $lt 小于
  • $lte 小于等于
  • $ne 不等于
  • $in 在多个值范围内
  • $nin 不在多个值范围内
  • $all 匹配数组中多个值
  • $regex 正则,用于模糊查询
  • $size 匹配数组大小
  • $maxDistance 范围查询,距离(基于LBS)
  • $mod  取模运算
  • $near 邻域查询,查询附近的位置(基于LBS)
  • $exists 字段是否存在
  • $elemMatch 匹配内数组内的元素
  • $within 范围查询(基于LBS)
  • $box 范围查询,矩形范围(基于LBS)
  • $center 范围醒询,圆形范围(基于LBS)
  • $centerSphere 范围查询,球形范围(基于LBS)
  • $slice 查询字段集合中的元素(比如从第几个之后,第N到第M个元素

常见的查询API,详细请查看文档

  • Model.deleteMany() 删除所有文档集合的匹配条件 相当于remove() 参数分别为:条件、操作、回调
  • Model.deleteOne() 删除匹配条件的文档集合的第一个文档 想当于remove() 参数分别为:条件、回调
  • Model.find() 查询文档 参数分别为:条件、选择字段、操作、回调
  • Model.findById() 通过_id字段查询文档 相当于findOne({ _id: id }) 参数分别为:id、选择字段、操作、回调
  • Model.findByIdAndDelete() 大多数情况使用它 通过_id字段查询文档并删除 相当于findOneAndDelete({ _id: id })的快捷方式 参数分别为:id、操作、回调
  • Model.findByIdAndRemove() 通过_id字段查询文档并移除 相当于findOneAndRemove({ _id: id })的快捷方式 参数分别为:id、操作、回调
  • Model.findByIdAndUpdate() 通过_id字段查询文档并更新 相当于findOneAndUpdate({ _id: id }, …) 参数分别为:id、更新字段、操作、回调
  • Model.findOne() 查询一个文档 参数分别为:条件、选择字段、操作、回调
  • Model.findOneAndDelete() 查询一个匹配的文档并删除 参数分别为:条件、操作、回调
  • Model.findOneAndRemove() 查询一个匹配的文档并移除 参数分别为:条件、操作、回调
  • Model.findOneAndUpdate() 查询一个匹配的文档并更新 参数分别为:条件、更新字段、操作、回调
  • Model.replaceOne() 覆盖一个已经存在的文档 相当于update() 参数分别为:条件、更新字段、操作、回调
  • Model.updateMany() 更新多个已经存在的文档 相当于update() 参数分别为:条件、更新字段、操作、回调
  • Model.updateOne() 更新一个已经存在的文档 相当于update() 参数分别为:条件、更新字段、操作、回调
  • Model.remove() 移除所有匹配的文档 参数分别为:条件、回调
  • Model.update() 更新一个文档 参数分别为:条件、更新字段、操作、回调

关于findByIdAndDelete()findByIdAndRemove()的区别,请移步官方文档

2.查询数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
let express = require('express');
let router = express.Router();

let mongoose = require('mongoose');
let People = require('../models/peopleModel');

router.get('/', function(req, res, next){

// 需使用body-parse中间件获取参数
let filters = { ...req.query };

console.log(filters, 'filter');

// 要查询的字段
let query = {};

if(filters.name){
query.name = filters.name
}
if(filters.age){
//查询年龄大于age参数
query.bookInfo = {$gt: filters.age}
}

People.find(query, null, {
limit: filters.pageSize,
skip: (filters.pageSize * filters.pageNum),
sort:'-createBy.age'
}, (err, data) => { //查找所有
if(err){
res.status(500).json({ error: err });
}else{
res.json({ code: 1, data: data });
}
})
});

module.exports = router;

当前端传相应的数据过来时,这边通过过滤和提取分页字段,利用limitskip操作来实现数据分页,也可以使用mongoose-paginate插件来简化分页操作,当前端传了对应的筛选字段过来,这边将按对应字段查询结果,并按age值倒序返回。

2.添加数据

添加数据需要用到mongoose的save()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
let express = require('express');
let router = express.Router();

let mongoose = require('mongoose');
let People = require('../models/peopleModel');

router.post('/', function(req, res, next){
const name = req.body.name,
age = req.body.age,
sex = req.body.sex,
class = req.body.class;

const newPeople = new People({
name,
age,
sex,
class
});

// 新增保存
newPeople.save((err, data) => {
if(err){
res.status(500).json({ error: err });
}else{
res.json({ code: 1, data: data });
}
});
});

module.exports = router;

3.修改数据

数据的修改需要用到_id字段,这个字段会在MongoDB数据库每增加一条新的记录时自动生成,也是唯一标识,同时,需要用到findByIdAndUpdate()方法来操作数据更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
let express = require('express');
let router = express.Router();

let mongoose = require('mongoose');
let People = require('../models/peopleModel');

router.post('/', function(req, res, next){
const _id = req.body._id,
name = req.body.name,
age = req.body.age,
sex = req.body.sex,
class = req.body.class;

const updateFields = {
_id,
name,
age,
sex,
class
};
// 通过_id更新指定指字段
People.findByIdAndUpdate({_id, _id}, updateFields, (err, data) => {
if(err){
res.status(500).json({ error: err });
}else{
res.json({ code: 1, data: data })
}
});
});

module.exports = router;

4.删除数据

数据的删除涉及到单条数据的删除和批量删除,可以通过传单个id字符或者id字符串数组来实现不同的删除功能,需要用到$in条件操作符和remove()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
let express = require('express');
let router = express.Router();

let mongoose = require('mongoose');
let People = require('../models/peopleModel');

router.post('/', function(req, res, next){
let ids = req.body._id;
let condition;
if(Array.isArray(ids)){
condition = {
_id: { $in: ids }
}
}else{
condition = {
_id: ids
}
}

People.remove(condition, (err, data) => {
if(err){
res.status(500).json({ error: err });
}else{
res.json({ code: 1, data: data })
}
})
});

module.exports = router;

至此,mongoose对于MongoDB的增删查改操作案例都实现了,相信大家会对MongoDB的操作有个较好的入门。