irpas技术客

node中使用mongoose_qq_40526866_node 使用mongoose

irpas 5723

下载 mongoose npm install mongoose 引入 mongoose 并连接数据库 const mongoose = require('mongoose') const DB_URL = 'mongodb://localhost/mongoose-test' mongoose.connect(DB_URL,{useNewUrlParser:true,useUnifiedTopology:true }, (err) => { if (err) return console.log(err) console.log('数据库成功连接') }) // 这种也可以看数据库是否连接成功 mongoose.connection.on('connected', () => console.log('数据库连接成功')) mongoose.connection.on('error', () => console.log('数据库连接异常')) mongoose.connection.on('disconnectied', () => console.log('数据库连接断开')) 定义Schema

数据库中的Schema,为数据库对象的集合。schema 是 mongoose 里会用到的一种数据模式,可以理解为表结构的定义;每个 schema 会映射到 mongodb 中的一个 collection,他不具备操作数据库的能力

// 设计 users 表(集合) 定义一个Schema Schema里面的对象和数据库表里面的字段需要一一对应 const UserSchema = new mongoose.Schema({ name: String, age: Number, status: 'number' }) /* 定义数据库模型 操作数据库 model里面的第一个参数 要注意:首字母大写、要和数据库 (集合) 名称对应 这个模型会和模型名称相同的复数的数据库建立连接:如通过下面方法创建,那么这个模型将会操作 users 这个表(集合) 复数 >==== 会给名字多加个s 如:User ===> users Phone ===> phones */ const User = mongoose.model('User', UserSchema) // 默认会操作users表 // const User = mongoose.model('User', UserSchmea, 'user') // 默认会操作user表 // 查询 User.find({}, (err, doc) => { if (err) { console.log(err) } else { console.log(doc) } }) 查询数据 const User = mongoose.model('User', UserSchema) // {查找 status 是1的} ,{只显示name和age, _id不显示},{找两条数据},(回调函数) User.find({ status: 1 }, {name: 1, age: 1, _id: 0}, {limit: 2}, (err, doc) => { if (err) return console.log(err) console.log(doc) }) User.find({}, (err, doc) => { if (err) { console.log(err) } else { console.log(doc) } }) 添加数据 单条添加 const User = mongoose.model('User', UserSchema) /* 先实例化 Model 通过实例化 User Model 创建添加的数据 在实例 .save() */ const newUser = new User({ // 实例化模型 传入增加的数据 name: '李四', age: 18, status: 1 }) // 第二个参数返回的是 添加成功的数据 newUser.save((err, v) => { if (err) return console.log(err) console.log(v) console.log('添加成功') }) 添加数据 多条添加 const User = mongoose.model('User', UserSchema) // 定义数据 let arr = [ { name: '小猪', age: 13, status: 0 }, { name: '小明', age: 32, status: 1 }, { name: '小红', age: 20, status: 1 }, { name: '小赖', age: 22, status: 1 }, { name: '小狗', age: 50, status: 1 }, { name: '小力', age: 10, status: 0 } ] // 使用 insertMany 插入多条数据 // doc 就是你添加成功之后给你返回的数据 User.insertMany(arr, (err, doc) => { if (err) return console.log(err) console.log('插入成功') console.log(doc) }) // 方法2 let newArr = new Array() arr.forEach((value, index) => { const info = new User(value) newArr.push(info) }) User.insertMany(newArr, (err, doc) => { if (err) return console.log('数据添加失败') console.log(doc) console.log('数据添加成功') }) 修改数据 const User = mongoose.model('User', UserSchema) // 把name的值是小四的字段里,age的值改成14 User.updateOne({ 'name': '小四' }, { 'age': 14 }, (err, res) => { if (err) return console.log('更新失败') console.log(res) console.log('更新成功') }) 删除数据 const User = mongoose.model('User', UserSchema) // 删除一个status是0的 User.deleteOne({ status: 0 }, (err, doc) => { if (err) return console.log(err) console.log(doc) }) // 删除所有 status是0的 User.deleteMany({ status: 0 }, (err, doc) => { if (err) return console.log(err) console.log(doc) }) Getters与Setters 自定义修饰符

Getters:

const UserSchema = new mongoose.Schema({ name: { type: String, get(params) { return '测试' + params } }, age: Number, status: 'number' }) const User = mongoose.model('User', UserSchema) const newUser = new User({ name: '小龙', age: 18, status: 1, url: 'https://·' }) console.log(newUser.name) // 测试小龙

Setters:

const UserSchema = new mongoose.Schema({ name: { type: String }, age: Number, status: 'number', url: { type: String, set(parmas) { if (!parmas) return '' const isHttp = parmas.indexOf('http://') const isHttps = parmas.indexOf('https://') if (isHttp !== 0 && isHttps !== 0) return 'http://' + parmas return parmas } } }) const User = mongoose.model('User', UserSchema) const newUser = new User({ name: '小龙', age: 18, status: 1, url: '·' }) console.log(newUser) /* { name: '小龙', age: 18, status: 1, url: 'http://·', _id: new ObjectId("61fb5217081f1e60d8711b0e") } */ mongoose 索引

索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询优化技巧。

mongoose 中除了以前创建索引的方式,我们也可以在定义Schema的时候指定创建索引

const DeviceSchema = new mongoose.Schema({ sn: { type: String, //唯一索引 unique: true }, name: { type: String, // 普通索引 index: true } }) Model 的静态方法和实例方法

静态方法

const UserSchema = new mongoose.Schema({ name: String, age: Number, status: 'number' }) // 封装静态查询方法 UserSchema.statics.findByAge = function(age, callback) { this.find({age}, (err, docs) => { callback(err, docs) }) } const User = mongoose.model('User', UserSchema) User.findByAge('30', (err, res) => { if (err) return console.log(err) console.log(res) })

实例方法 (基本不用)

const UserSchema = new mongoose.Schema({ name: String, age: Number, status: 'number' }) // 实例方法 UserSchema.methods.print = function() { console.log(this) } const User = mongoose.model('User', UserSchema) const user = new User({ name: '小刘', age: 18, status: 1 }) user.print() /* { name: '小刘', age: 18, status: 1, _id: new ObjectId("61fb6b16f14ac45e7d3d9b25") } */ Mongoose 数据校验

mongoose数据校验是指用户通过mongoose给mongodb数据库增加数据的时候,对数据的合法性进行的验证。

在mongoose里面定义Schema的时候,通过设置字段类型,修饰符、默认参数 、数据校验等都是为了数据库数据的一致性。

校验参数 属性方法说明require表示这个数据必须传入max用于Number类型数据,最大值min用于Number类型数据,最小值enum枚举类型,要求数据必须满足枚举值 enum: [‘0’, ‘1’, ‘2’]match增加的数据必须符合 match (正则) 的规则maxlength最大值minlength最小值validate(v)自定义验证trim去除两边的空格
const UserSchema = new mongoose.Schema({ name: { type: String, required: true, // 必须传入 trim: true, // 修饰符 去除两边空格 maxlength: 8, // 最大8位 minlength: 2, // 最小2位 }, age: { type: Number, max: 100, // 最大值是100 min: 8 // 最小值是8 }, status: { type: Number, enum: [0, 1] // 只能传入0和1 }, url: { type: String, match: /^http:\/\/(.*)/i } }) const User = mongoose.model('User', UserSchema) const user = new User({ name: 'zss', age: 12, status: 0, url: 'http://' }) user.save() /* name值为空 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: name: Path `name` is required.\ */ /* name长度小于2 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: name: Path `name` (`z`) is shorter than the minimum allowed length (2). */ /* name长度大于8 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: name: Path `name` (`zsdsadsadas`) is longer than the maximum allowed length (8). */ /* status只能传入0和1 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: status: `50` is not a valid enum value for path `status`. */ /* age最大值是100,最小值是8 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: age: Path `age` (102) is more than maximum allowed value (100). */ /* url必须以http://开头 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: url: Path `url` is invalid (http:/). */

自定义校验

const UserSchema = new mongoose.Schema({ num: { type: Number, validate(value) { return value % 2 === 0 } } }) const User = mongoose.model('User', UserSchema) const user = new User({ num: 7 }) user.save() /* num 必须是偶数 UnhandledPromiseRejectionWarning: ValidationError: User validation failed: num: Validator failed for path `num` with value `7` */ Mongoose 中使用 aggregate 聚合管道

$ne:表示not equals 就是不等于的意思

查询某字段不为空的数据 db.user.find({fieldName: {$ne:null}})

查询字段等于空的数据 db.user.find({fieldName: {$eq:null}})

$exists:表示是否存在。值为false表示不存在,值为true表示存在

查询某字段不为空的数据 db.user.find({fieldName:{$exists:true}})

查询某字段不存在的数据 db.user.find({fieldName:{$exists:false}})

mongoose中获取ObjectID

引入 mongoose 使用 mongoose.Types.ObjectId('xczxcxzczxcz3234')

const User = mongoose.model('User', UserSchema) User.aggregate([ { $lookup: { from: 'phones', localField: 'phone_id', foreignField: '_id', as: 'user_phone' } }, { $match: { 'phone_id': { $exists: true } } } ], (err, docs) => { console.log(docs) }) 多表关联查询 /* from: user 这是要关联 user 表 localField 这是要跟 article 表里的 classify_id 字段进行关联 foreignField 这是要跟 user 表里的 _id字段进行关联 as 这是别名,就是给这个新的数据起个名 */ const { Article } = require('./db') // 要关联多个表就继续往下写 { $lookup: {...} } Article.aggregate([ { $lookup: { from: 'articlecate', localField: 'classify_id', foreignField: '_id', as: 'cate' } }, { $lookup: { from: 'user', localField: 'author_id', foreignField: '_id', as: 'user' } } ], (err, docs) => { console.log(JSON.stringify(docs)) })

多表关联查询结果

[ { // 这个是article表 "_id": "61fb9de67d8a21e93c2eaad2", "title": "第一个科技文章", "classify_id": "61fb9619215153325d17a193", "author_id": "61fb9bdee12c49d0f430d216", "author_name": "张三", "description": "这是张三发布的第一个科技文章,属于科技分类", "content": "这是科技 文章的内容,此处省略一万字", "__v": 0, // article表 关联了 articlecate表 并且起名叫cate "cate": [{ "_id": "61fb9619215153325d17a193", "title": "科技新闻", "description": "科技新闻的描述。。。", "__v": 0 }], // article表 关联了 user表 并且起名叫user "user": [{ "_id": "61fb9bdee12c49d0f430d216", "username": "zhangsan", "password": "123456", "name": "张三", "age": 18, "sex": "男", "tel": 14895466411, "__v": 0 }] }, { "_id": "61fb9de67d8a21e93c2eaad3", "title": "第二个科技文章", "classify_id": "61fb9619215153325d17a193", "author_id": "61fb9bdee12c49d0f430d216", "author_name": "张三", "description": "这是张三发布的第二个科技文章,属于科技分类", "content": "这是科技文章的内容,此处省略一万字", "__v": 0, "cate": [{ "_id": "61fb9619215153325d17a193", "title": "科技新闻", "description": "科技新闻的描述。。。", "__v": 0 }], "user": [{ "_id": "61fb9bdee12c49d0f430d216", "username": "zhangsan", "password": "123456", "name": "张三", "age": 18, "sex": "男", "tel": 14895466411, "__v": 0 }] }, { "_id": "61fb9de67d8a21e93c2eaad4", "title": "第一个金融文章", "classify_id": "61fb96563188bc6d398ed013", "author_id": "61fb9bdee12c49d0f430d216", "author_name": "张三", "description": "这是张三发布的第一个金融文章,属于金融分类", "content": "这是金融文章的内容,此处省略一万字", "__v": 0, "cate": [{ "_id": "61fb96563188bc6d398ed013", "title": "金融新闻", "description": "金融新闻的描述。。。", "__v": 0 }], "user": [{ "_id": "61fb9bdee12c49d0f430d216", "username": "zhangsan", "password": "123456", "name": "张三", "age": 18, "sex": "男", "tel": 14895466411, "__v": 0 }] } ] 多表查询 populate //Article表 // 分类ID classify_id: { type: mongoose.Types.ObjectId, ref: 'ArticleCate' // 关联的Model }, // 作者ID author_id: { type: mongoose.Types.ObjectId, ref: 'User' }, // app.js const { Article } = require('./db') // populate('classify_id') 需要关联的字段 Article.find({}).populate('classify_id').populate('author_id').exec((err, docs) => { console.log(docs) })

这是返回的数据,这里不能起别名,直接就覆盖字段了

{ _id: new ObjectId("61fb9e5735882d989cf8833a"), title: '第二个美食文章(小红)', classify_id: { _id: new ObjectId("61fb9645c342558ade4e1f3c"), title: '美食新闻', description: '美食新闻的描述。。。', __v: 0 }, author_id: { _id: new ObjectId("61fb9bdee12c49d0f430d219"), username: 'xiaohong', password: '123456', name: '小红', age: 18, sex: '女', tel: 15478932000, __v: 0 }, author_name: '小红', description: '这是小红发布的第二个美食文章,属于美食分类', content: '这是美食文章的内容,此处省略一万字', __v: 0 }

性能还是推荐使用 aggregate


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #node #使用Mongoose #下载 #mongoosenpm #install #mongoose引入 #Mongoose #并连接数据库const