环境搭建
npm i egg-mongoose --save
配置
exports.mongoose = {
enable: true,
package: 'egg-mongoose',
}
exports.mongoose = {
url: 'mongodb://127.0.0.1:27017/example',
options: {},
}
使用
module.exports = (app) => {
const mongoose = app.mongoose
const Schema = mongoose.Schema
const UserSchema = new Schema({
name: { type: String },
age: { type: Number, default: 0 },
posts: [
{
type: Schema.Types.ObjectId,
ref: 'Post',
},
],
})
return mongoose.model('User', UserSchema)
}
module.exports = (app) => {
const mongoose = app.mongoose
const Schema = mongoose.Schema
const PostSchema = new Schema({
title: { type: String },
content: { type: String },
})
return mongoose.model('Post', PostSchema)
}
mongoose 预定义模式修饰符
- 预定义模式修饰符:
lowercase、uppercase、trim、match、enum、minlength、maxlength、min、max、default、select、validate、get、set, alias,required
const userSchema = mongoose.Schema({
name: {
type: String,
lowercase: true,
trim: true,
},
gender: {
type: String,
enum: 1 || 2,
default: 1,
},
status: {
type: Number,
min: 0,
max: 1,
},
age: {
type: Number,
min: [18, '未成年'],
max: [60, '已退休'],
},
})
Getters 与 Setters 自定义修饰符
const userSchema = mongoose.Schema({
name: {
type: String,
lowercase: true,
trim: true,
get: (val) => {
return val + '123'
},
set: (val) => {
return val + '456'
},
},
})
mongoose 索引
const DeviceSchema = new mongoose.Schema({
sn: {
type: Number,
unique: true,
},
name: {
type: String,
index: true,
},
age: {
type: Number,
index: true,
},
})
mongoose 内置 curd
db.collection.deleteMany({ age: { $gte: 22 } })
db.collection.deleteOne({ age: { $gte: 22 } })
db.collection.find({ age: { $gte: 22 } })
db.collection.findById('5f9b0b3b9b9b7c1b4c3b3b3b')
db.collection.findByIdAndDelete('5f9b0b3b9b9b7c1b4c3b3b3b')
db.collection.findByIdAndRemove('5f9b0b3b9b9b7c1b4c3b3b3b')
db.collection.findByIdAndUpdate('5f9b0b3b9b9b7c1b4c3b3b3b', { age: 23 })
db.collection.findOne({ age: { $gte: 22 } })
db.collection.findOneAndDelete({ age: { $gte: 22 } })
db.collection.findOneAndRemove({ age: { $gte: 22 } })
db.collection.findOneAndReplace({ age: { $gte: 22 } }, { age: 23 })
db.collection.findOneAndUpdate({ age: { $gte: 22 } }, { age: 23 })
db.collection.replaceOne({ age: { $gte: 22 } }, { age: 23 })
db.collection.updateMany({ age: { $gte: 22 } }, { age: 23 })
db.collection.updateOne({ age: { $gte: 22 } }, { age: 23 })
扩展 mongoose 静态方法
const userSchema = mongoose.Schema({
name: {
type: String,
lowercase: true,
trim: true,
get: (val) => {
return val + '123'
},
set: (val) => {
return val + '456'
},
},
})
userSchema.statics.findByName = function (name) {
return this.find({ name: new RegExp(name, 'i') })
}
userSchema.methods.findByName = function (name) {
return this.model('User').find({ name: new RegExp(name, 'i') })
}
module.exports = mongoose.model('User', userSchema)
const User = require('./model/user')
User.findByName('张三').then((res) => {
console.log(res)
})
const User = require('./model/user')
const user = new User()
user.findByName('张三').then((res) => {
console.log(res)
})
mongoose 验证器
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: [true, '用户名不能为空'],
},
age: {
type: Number,
max: 120,
min: 0,
},
status: {
type: String,
enum: ['success', 'error'],
},
phone: {
type: Number,
match: /^1[3456789]\d{9}$/,
},
desc: {
type: String,
validate: {
validator: function (v) {
return v.length > 10
},
message: '描述信息不能少于10个字符',
},
},
})
mongoose 简单 curd
module.exports = (app) => {
class UserController extends app.Controller {
async index() {
const { ctx } = this
const users = await ctx.model.User.find({})
ctx.body = users
}
async create() {
const { ctx } = this
const user = await ctx.model.User.create(ctx.request.body)
ctx.body = user
}
async updateUser() {
const { ctx } = this
const user = await ctx.model.User.updateOne(
{ _id: ctx.params.id },
ctx.request.body
)
ctx.body = user
}
async deleteUser() {
const { ctx } = this
const user = await ctx.model.User.deleteOne({ _id: ctx.params.id })
ctx.body = user
}
}
return UserController
}
module.exports = (app) => {
app.get('/', 'home.index')
app.get('/user', 'user.index')
app.post('/user', 'user.create')
app.put('/user/:id', 'user.updateUser')
app.delete('/user/:id', 'user.deleteUser')
}
关联查询
async index() {
const { ctx } = this
const users = await ctx.model.User.find({}).populate('posts')
ctx.body = users
}
async show() {
const { ctx } = this
const user = await ctx.model.User.findById(ctx.params.id).populate('posts')
ctx.body = user
}
async index() {
const { ctx } = this
const users = await ctx.model.User.find({}).populate('posts').select('title content')
const page = Number(ctx.query.page) || 1
const limit = Number(ctx.query.limit) || 10
const posts = await ctx.model.Post.find({})
.skip((page - 1) * limit)
.limit(limit)
.sort({ _id: -1 })
const total = await ctx.model.Post.countDocuments({})
ctx.body = {
users,
posts,
postsCount: total
}
}
聚合查询
async index() {
const { ctx } = this
const page = Number(ctx.query.page) || 1
const limit = Number(ctx.query.limit) || 10
const users = await ctx.model.User.aggregate([
{
$lookup: {
from: 'posts',
localField: 'posts',
foreignField: '_id',
as: 'postsList'
}
},
{
$project: {
name: 1,
age: 1,
postsList: {
title: 1,
content: 1
}
}
},
{
$skip: (page - 1) * limit
},
{
$limit: limit
},
{
$sort: {
_id: -1
}
}
])
const total = await ctx.model.User.countDocuments({})
ctx.body = {
users,
postsCount: total
}
}
参考