mongoose安装和使用(超详细)

发布时间:2024年01月17日

一.简介

介绍

  • Mongoose 是一个让我们可以通过Node来操作MongoDB数据库的一个模块

  • Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装

  • 大多数情况下,他被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型装换等好处

  • 基于MongoDB驱动,通过关系型数据库的思想来实现非关系型数据库

优势/好处

  • 为文档创建模式结构(Schema),也可以说是约束

  • 对模型中的对象/文档进行验证

  • 数据可以通过类型装换装换为对象模型

  • 可以使用中间件来应用业务逻辑挂钩

  • 相比MongoDB驱动更容易

new Object

Schema(模式对象)

——Schema 对象定义约束了数据库中的文档结构

Model

——Model 对象作为集合中的所有文档的表示,相当于MongoDB中的collection,它的每一个实例就是一个document文档

Document

——Document表示集合中的具体文档,相当于collection中的一个具体文档

关系:Schema生成Model,Model创造Document

模式(Schemas)

  • 每个 schema 都会映射到一个 MongoDB collection 并定义这个collection里的文档结构

  • 创建一个 schema 对象

const mongoose = require('mongoose')
//调用 Schema
const Scheme = mongoose.Schema

//创建 schema 对象
var stuSchema = new Schema({
? ? name: String,
? ? age: Number,
? ? gender:{
? ? ? ? type: String,
? ? ? ? default:'male' //定义默认类型
? ? },
? ? addr: String
})

  • 在Schema定以后添加字段时需要使用 add() 方法

var stuSchema = new Schema({
? ? {...},
? ? { timestamps:true }
})

_id

当未定义_id字段时 mongoose 会为每一个文档自动添加一个不重复的_id,类型为ObiectId(在查询语句中需要通过 findById() 才能查询)

二.安装使用mongoose

前提:安装MongoDB,Nodejs

1.下载安装Mongoose

?npm i mongoose

2.项目中引入mongoose

var mongoose = require(‘mongoose’)

3.连接数据库

mongoose.connect(‘mongodb://数据库ip地址 : 端口号( 默认端口27017可以省略 )/数据库名’)

数据库连接成功事件

补充
将成功回调的on改成once
事件回调函数只执行一次
mongoose.connection.once(‘open’ , () => {})

数据库断开事件

mongoose.connection.once(‘close’ , () => {})

4.创建Schema(模式)对象

var stuSchema = new Schema({})

  • 通过Schema创建Model

  • Model 代表的是数据库中的集合,通过Model才能对数据库进行操作

5.映射

var stuModel = mongoose.model(‘student’,stuSchema)

参数

  1. 要映射的集合名

  2. 创建的约束(Schema对象)

6.通过映射返回的值对数据库进行增、删、改、查

7.断开数据库连接(一般不使用)

const mongoose = require('mongoose');

// 连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/user');

// 设置连接成功的回调
mongoose.connection.once('open', () => {
? ? if (mongoose.connection.readyState === 1) {
? ? console.log("连接成功");

? ? // 创建文档的结构对象
? ? let BookSchema = new mongoose.Schema({
? ? ? ? name: {
? ? ? ? ? ? type: String,
? ? ? ? ? ? required: true
? ? ? ? },
? ? ? ? author: String,
? ? ? ? price: Number
? ? });

? ? // 创建模型对象
? ? let BookModel = mongoose.model('books', BookSchema);

? ? // 数据插入
? ? BookModel.create(
? ? ? ? {
? ? ? ? ? ? name: '西游记',
? ? ? ? ? ? author: '哈哈',
? ? ? ? ? ? price: 19.9,
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? name: '红楼梦',
? ? ? ? ? ? author: '曹雪芹',
? ? ? ? ? ? price: 19.9,
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? name: '水浒传',
? ? ? ? ? ? author: '111',
? ? ? ? ? ? price: 19.9,
? ? ? ? },
? ? ? ? {
? ? ? ? ? ? name: '三国演义',
? ? ? ? ? ? author: '2222',
? ? ? ? ? ? price: 19.9,
? ? ? ? },
? ? ? ? (err, data) => {
? ? ? ? ? ? if (err) {
? ? ? ? ? ? ? ? console.log(err);
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? console.log(data);
? ? ? ? ? ? // 插入数据后关闭连接
? ? ? ? ? ? mongoose.disconnect();
? ? ? ? }
? ? );
? ? // 数据删除
? ? // ? BookModel.remove({name:/西游记/},function(err){})
}
});

// 设置连接错误的回调
mongoose.connection.on('error', () => {
? ? console.log("连接失败");
});

// 设置连接关闭的回调
mongoose.connection.on('close', () => {
? ? console.log("连接关闭");
});
?

创建文档的结构对象

设置集合中文档的属性以及属性值的类型

Let BookSchema= new mongoose.Schema({
name: String
author: String;
price:Number
})

创建模型对象 对稳定操作的封装对象

Let BookModel= mongoose.model( ' books ',BookSchema)
集合名称,结构对象

文档新增

create()
  • 操作模型

  • Model.create(doc(s), [callback])

  • 参数:

    [doc(s)]:文档对象或文档对象数组

    [callback]:回调函数

?// 数据插入
? stuModel.create({name:"小明",grades:68},{name:"小红",grades:80},(err,doc1,doc2) => {
? ? ? ? ? ?if(!err){
? ? ? ? ? ? ?? ?console.log(doc1)
? ? ? ? ? ? ?? ?//{ _id: 6017be2d77c8dd01242624bb, name: '小明', grades: 68, __v: 0 }
? ? ? ? ? ? ?? ?console.log(doc2)
?? ??? ??? ??? ?//{ _id: 6017be2d77c8dd01242624bc, name: '小红', grades: 80, __v: 0 }
? ? ? ? ?? ?}
? ? ? ? })
?

save()
  • 操作的是文档

  • Model.prototype.save([options], [options.safe], [options.validateBeforeSave], [fn])

?//链式调用 通过new 一个Model创建一个 document
? ? ? ? new stuModel({name:"小明",grades:68}).save((err,docs) => {
? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? console.log(docs)
? ? ? ? ? ? ? ? //{ _id: 6017bd1cf4cc8544d8ed2a8a, name: '小明', grades: 68, __v: 0 }
? ? ? ? ? ? }
? ? ? ? })

insertMany()
  • Model.insertMany(doc(s), [options], [callback])

  • 返回值为一个数组

?//链式调用 通过new 一个Model创建一个 document
? ? ? ? stuModel.insertMany({name:"小明",grades:68},{name:"小芳",grades:94},(err,docs) => {
? ? ? ? ? ?if(!err){
? ? ? ? ? ? ?? ?console.log(docs)
? ? ? ? ? ? ?? ?/*[{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },
? ? ? ? ? ? ? ? ? ?{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }]*/
? ? ? ? ?? ?}
? ? ? ? })

文档查询

find()
  • Model.find(conditions, [projection], [options], [callback])

  • 参数

    conditions:查询条件

    [projection]:控制返回字段

    [options]:配置查询参数

    [callback]:回调函数–function(err,docs){}

? ?// 数据查询
? ? ? ? // BookModel.find((err, docs) => {
? ? ? ? // ? ? if (!err) {
? ? ? ? // ? ? ? ? console.log(docs)
? ? ? ? // ? ? }
? ? ? ? // })

findById()

Model.findById(conditions, [fields], [options], [callback])

var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',(err) => {
? ? if(!err){
? ? ? ? var schema = new mongoose.Schema({name:String,grades:Number})
? ? ? ? var stuModel = mongoose.model('grades',schema)
? ? ? ? //保存查询数据的_id
? ? ? ? var aIDArr = []
? ? ? ??
? ? ? ? //查询所有数据
? ? ? ? stuModel.find((err,docs) => {
? ? ? ? ? ?if(!err){
? ? ? ? ? ? ?? ?docs.forEach((item,index,arr)=>{
? ? ? ? ? ? ? ? ? ? aIDArr.push(item._id)
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? //显示第 0 个元素的所有字段
? ? ? ? ? ? ? ? stuModel.findById(aIDArr[0],(err,doc)=>{
? ? ? ? ? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? ? ? ? ? console.log(doc)
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ?// { _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? //显示第 0 个元素且只输出name字段
? ? ? ? ? ? ? ? stuModel.findById(aIDArr[0],{name:1,_id:0},(err,doc)=>{
? ? ? ? ? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? ? ? ? ? console.log(doc)
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ?// { name: '小明' }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? //显示第 0 个元素且输出最少的字段(_id默认输出)
? ? ? ? ? ? ? ? stuModel.findById(aIDArr[0],{lean:true},(err,doc)=>{
? ? ? ? ? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? ? ? ? ? console.log(doc)
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ?// { _id: 6017befb5c36d64d08b72576 }
? ? ? ? ?? ?}
? ? ? ? })
? ? }
})

注:conditions写一个id值就可以了,返回单个文档

findOne()
  • 返回查询到的数据的第一个

?// 返回查询到的数据的第一个
? ? ? ? BookModel.findOne({price:{$gt:10}},(err,doc) => {
? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? ?console.log(doc)
? ? ? ? ? ? ?}
? ? ? ? ?})

复杂查询【$where】
  • $where 可以使用任意的 JavaScript 作为查询的一部分,包含JavaScript 表达式的字符串或者函数

?// 字符串 es5中this与obj指向一样,es6中只能用obj
? ? ? ? BookModel.find({$where:"this.name == this.author" || "obj.name == obj.author"},(err,doc) => {
? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? ?console.log(doc)
? ? ? ? ? ? ?}
? ? ? ? ?})
? ? ? ? ?//函数
? ? ? ? ?BookModel.find({$where:function() {
? ? ? ? ? ? return this.name == this.author || obj.name == obj.author
? ? ? ? }},(err,doc) => {
? ? ? ? ? ? if(!err){
? ? ? ? ? ? ? ? ?console.log(doc)
? ? ? ? ? ? ?}
? ? ? ? ?})

常用查询条件

stuModel.find({grades:{$gt:90}},(err,docs)=>{
? ? console.log(docs);
})

特定类型查询

const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades', Schema);

// 按test从小到大排序
stuModel.find().sort('test').exec((err,docs)=>{
? console.log(docs)
})
// 按test从大到小排列
stuModel.find().sort('-test').exec((err,docs)=>{
? console.log(docs)
})
// 跳过1个,显示其他
stuModel.find().skip(1).exec((err,docs)=>{
? console.log(docs)
})
// 显示2个
stuModel.find().limit(2).exec((err,docs)=>{
? console.log(docs)
})
// 显示name、grades字段,不显示_id字段
stuModel.find().select('name grades -_id').exec((err,docs)=>{
? console.log(docs)
})
// 跳过第1个后,只显示2个数据,按照grades由大到小排序,且不显示_id字段
stuModel.find().skip(1).limit(2).sort('-grades').select('-_id').exec((err,docs)=>{
? console.log(docs)
? /*[{ name: '小明', grades: 78, __v: 0, test: 1 },
? ? ?{ name: '小花', grades: 76, test: 4, __v: 0 }]*/
})
// 显示集合stuModel中的文档数量
stuModel.find().count((err,count)=>{
? console.log(count)
? //6
})
// 返回集合stuModel中的grades的值
stuModel.find().distinct('grades',(err,distinct)=>{
? console.log(distinct)
? //[ 46, 52, 60, 76, 78, 94 ]
})

文档更新

update()
  • Model.update(conditions, doc, [options], [callback])

  • 参数

    conditions:查询条件

    doc:需要修改的数据(插入的数据)

    [options]:控制选项

safe (boolean): 默认为true。安全模式。
upsert (boolean): 默认为false。如果不存在则创建新记录。
multi (boolean): 默认为false。是否更新多个查询记录。
runValidators: 如果值为true,执行Validation验证。
setDefaultsOnInsert: 如果upsert选项为true,在新建时插入文档定义的默认值。
strict (boolean): 以strict模式进行更新。
overwrite (boolean): 默认为false。禁用update-only模式,允许覆盖记录。

  • [callback]:回调函数

  • 若设置了查询条件,当数据库不满足时默认什么也不发生

  • update() 方法中的回调函数不能省略,否则数据不会更新,当回调无有用信息时可以使用exec()简化

stuModel.update({grades:{$gt:80}},{test:40},function(err,raw){
? ? //{ n: 1, nModified: 1, ok: 1 }
? ? console.log(raw);
})
如果要同时更新多个记录,需要设置options里的multi为true。
?temp.update({name:/a/},{age: 10},{multi:true},function(err,raw){
? ? ? ? ? ? //{ n: 2, nModified: 2, ok: 1 }
? ? ? ? ? ? console.log(raw);
? ? ? ? })

updateOne()
  • Model.updateOne(conditions, doc, [options], [callback])

  • 与update()相似,唯一区别为updateOne() 默认更新一个文档,即使设置{multi:true}也无法只更新一个文档

updateMany()
  • Model.updateMany(conditions, doc, [options], [callback])

  • 与update()相似,唯一区别为updateMany() 默认更新多个文档,即使设置{multi:false}也无法只更新一个文档

find()+save()】 【findOne() + save()

用于复杂更新

const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student',err=>{
? if(!err){
? ? ?var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
? ? ?var stuModel = mongoose.model('grades',Schema)
?? ?
? ? ?//查询成绩小于60的数据,并在其名字后添加‘:差生’字段
? ? ?stuModel.find({grades:{$lt:60}},(err,docs)=>{
? ? ? console.log(docs);
? ? ? /*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: '小红',grades: 52,__v: 0},
? ? ? ? {test: 0,_id: 6017c455ba09d355a49ec8ec,name: '小刚',grades: 46,__v: 0}]*/
? ? ??
? ? ? docs.forEach((item,index,arr) => {
? ? ? ? item.name += ':差生'
? ? ? ? //将修改后的数据保存
? ? ? ? item.save()
? ? ? })
? ? ? console.log(docs)
? ? ? /*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: '小红:差生',grades: 52,__v: 0},
? ? ? ? {test: 0,_id: 6017c455ba09d355a49ec8ec,name: '小刚:差生',grades: 46,__v: 0}]*/
? ? })
? }
})
?

文档删除

【remove()】
  • 会删除符合条件的所有数据

// 数据删除
BookModel.remove({name:/西游记/},function(err){})

【findOneAndRemove()】
  • 删除符合条件的一条数据

  • Model.findOneAndRemove(conditions, [options], [callback])

  • 回调不可省略,但可以使用exec() 简写

stuModel.findOneAndRemove({name:/差生/}).exec()

【findByIdAndRemove()】
  • 通过id删除数据(id是唯一的)

  • Model.findByIdAndRemove(conditions, [options], [callback])

  • 回调不可省略,但可以使用exec() 简写

文章来源:https://blog.csdn.net/Mangcun_tutu/article/details/135586349
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。