Mongoose(7.0.4)的安装与使用

一、简介

  • 基于 node-mongodb-native MongoDB nodejs 驱动,可以在异步的环境下执行。
  • 它是针对 MongoDB 操作的一个对象文档型数据库,封装了MongoDB 对文档的的一些增删改查等常用方法
  • 从6.0.0版开始,Mongoose中的方法不再接受回调作为最后一个参数,而是返回一个promise

1.1 准备工作

  • 安装mongoose,当前最新版本为 7.0.4
npm i mongoose
  • 引用mongoose
const mongoose = require('mongoose');
  •  连接mongodb服务 ,默认端口是27017
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

1.2 连接数据库

const mongoose = require('mongoose');

mongoose.set('strictQuery',true);
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

//设置回调
//连接成功的回调
// mongoose.connection.on('open',()=>{
//     console.log('sucess')
// });
//事件回调函数只执行一次
mongoose.connection.once('open',()=>{
    console.log('sucess')
});
//设置连接错误的回调
mongoose.connection.on('error',()=>{
    console.log('error')
});
//设置连接关闭
mongoose.connection.on('close',()=>{
    console.log('close')
});

//延迟关闭
setTimeout(() => {
    mongoose.disconnect();
}, 2000);

二、CRUD(增删改查)

  • Mongoose 里,一切都始于Schema。Schema的功能不只是定义文档结构和属性类型。它可以定义——
    • document 的 instance methods
    • model 的 static Model methods
    • 复合索引
  • 文档的生命周期钩子,也成为中间件
  • 每个 schema 都会映射到一个 MongoDB collection ,并定义这个collection里的文档的构成。
  • 文档 里每个属性的类型都会被转换为在 创建文档的结构对象时 定义对应的 SchemaTypes(模式类型)。
  • 允许使用的 SchemaTypes 有:
类型描述

String

字符串
Number数字
Date日期
BufferBuffer对象
Boolean布尔值
Mixed任意类型,需要使用 mongoose.Schema.Types.Mixed 指定
ObjectId对象ID,需要使用 mongoose.Schema.Types.ObjectId 指定,

 主要用于外键,适合联合查询

Array数组,也可使用 [  ] 来标识
Decimal128高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定

2.1 插入文档

const mongoose = require('mongoose');

mongoose.set('strictQuery', true);
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

//设置回调
//连接成功的回调
// mongoose.connection.on('open',()=>{
//     console.log('sucess')
// });
//事件回调函数只执行一次
mongoose.connection.once('open', () => {
    //1.创建文档的结构对象 设置集合中文档的属性以及属性值的类型
    let blogSchema = new mongoose.Schema({
        title: String,
        author: String,
        price: String,
        is_hot: Boolean,
        tags:[],
        pub_time:Date,
        test:mongoose.Schema.Types.Mixed, 
    });

    //2.创建模型对象 对文档操作的封装对象
    let BlogModel = mongoose.model('Blog', blogSchema);

    //3.新增
    BlogModel.create({
        title: '西游记',
        author: '吴承恩',
        price: 34,
        is_hot: true,
        tags:['鬼怪','人性'],
        pub_time:new Date(),
        test:26
    }).then((res) => {
        console.log(res)
        //4.关闭数据连接 项目运行过程中不会添加该代码
        mongoose.disconnect();
    }).catch((err) => {
        console.log(err)
    })
    //console.log('sucess')
});

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

> use test1
switched to db test1
> show collections
account
blogs
book
user

> db.blogs.find()
{ "_id" : ObjectId("6445353d87dd3243c3a24cd8"), "title" : "西游记", "author" : "吴承恩", "price" : "34", "is_hot" : true, "tags" : [ "鬼怪", "人性" ], "pub_time" : ISODate("2023-04-23T13:40:13.909Z"), "test" : 26, "__v" : 0 }

2.1.1 字段值验证

Mongoose有一些内置验证器,可以对字段进行验证

  • 必填项  (required: true)

  • 默认值  (default: '匿名')

  • 枚举值  (enum: ['言情', '志怪', '玄幻'])

  • 唯一值  (unique: true)

const mongoose = require('mongoose');

mongoose.set('strictQuery', true);
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

mongoose.connection.once('open', () => {
    //1.创建文档的结构对象 设置集合中文档的属性以及属性值的类型
    let BookSchema = new mongoose.Schema({
        title: {
            type: String,
            //表明该属性必填
            required: true,
            //设置为唯一值,想看到效果必须重建集合
            unique: true
        },
        author: {
            type: String,
            //默认值
            default: '匿名'
        },
        price: Number,
        style: {
            type: String,
            //枚举值
            enum: ['言情', '志怪', '玄幻']
        }

    });

    //2.创建模型对象 对文档操作的封装对象
    let BookModel = mongoose.model('books', BookSchema);

    //3.新增
    BookModel.create({
        //Path `title` is required.
        //MongoServerError: E11000 duplicate key error collection: test1.books index: title_1 dup key: { title: "xxx" }
        title: 'xxx',
        price: 30,
        // `xx` is not a valid enum value for path `style`.
        style: '志怪'

    }).then((res) => {
        console.log(res)
        //4.关闭数据连接 项目运行过程中不会添加该代码
        mongoose.disconnect();
    }).catch((err) => {
        console.log(err)
    })
    //console.log('sucess')
});

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

2.2 删除文档

  • 删除一条  deleteOne(条件)

  • 批量删除  deleteMany(条件)

const mongoose = require('mongoose');

mongoose.set('strictQuery', true);
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

mongoose.connection.once('open', () => {
    //1.创建文档的结构对象 设置集合中文档的属性以及属性值的类型
    let MovieSchema = new mongoose.Schema({
        title: {
            type: String,
            //表明该属性必填
            required: true,
            //设置为唯一值,想看到效果必须重建集合
            unique: true
        },
        author: {
            type: String,
            //默认值
            default: '匿名'
        },
        price: Number,
        style: {
            type: String,
            //枚举值
            enum: ['言情', '志怪', '玄幻']
        }

    });

    //2.创建模型对象 对文档操作的封装对象 
    //mongoose 会使用集合名称的复数创建集合 movie==>movies
    let MovieModel = mongoose.model('movie', MovieSchema);

    //3.删除一条
    // MovieModel.deleteOne({_id:'64453dc8503e3b434d863272'})
    // .then((res) => {
    //     console.log(res);
    //     console.log('删除成功!')
    //     mongoose.disconnect();
    // }).catch((err) => {
    //     console.log(err)
    // })
    //4.删除多条
    MovieModel.deleteMany({style:'玄幻'})
    .then((res) => {
        console.log(res);
        console.log('删除成功!')
        mongoose.disconnect();
    }).catch((err) => {
        console.log(err)
    })

    
});

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

2.3 更新文档

  • 更新一条  updateOne(条件)

  • 批量更新  updateMany(条件)

const mongoose = require('mongoose');

mongoose.set('strictQuery', true);
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

mongoose.connection.once('open', () => {
    //1.创建文档的结构对象 设置集合中文档的属性以及属性值的类型
    let BookSchema = new mongoose.Schema({
        title: {
            type: String,
            //表明该属性必填
            required: true,
            //设置为唯一值,想看到效果必须重建集合
            unique: true
        },
        author: {
            type: String,
            //默认值
            default: '匿名'
        },
        price: Number,
        style: {
            type: String,
            //枚举值
            enum: ['言情', '志怪', '玄幻']
        }

    });

    //2.创建模型对象 对文档操作的封装对象 
    //mongoose 会使用集合名称的复数创建集合 movie==>movies
    let BookModel = mongoose.model('movie', BookSchema);

    //3.更新一条
    // BookModel.updateOne({ title:"河西"},{price:9.9}).then((res) => {
    //     console.log(res)
    //     console.log('更新成功')
    //     mongoose.disconnect();
    // }).catch((err) => {
    //     //console.log(err)
    //     console.log('更新失败')
    // })

    //4.批量更新
    BookModel.updateMany({ author:"匿名"},{price:25}).then((res) => {
        console.log(res)
        console.log('更新成功')
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('更新失败')
    })

 
});

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

2.4 读取文档

  • 读取一条      findOne(条件)

  • 根据id获取  findById(id)

  • 批量更新      updateMany(条件)

const mongoose = require('mongoose');

mongoose.set('strictQuery', true);
//连接mongodb服务                           数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test1');

mongoose.connection.once('open', () => {
    //1.创建文档的结构对象 设置集合中文档的属性以及属性值的类型
    let BookSchema = new mongoose.Schema({
        title: {
            type: String,
            //表明该属性必填
            required: true,
            //设置为唯一值,想看到效果必须重建集合
            unique: true
        },
        author: {
            type: String,
            //默认值
            default: '匿名'
        },
        price: Number,
        style: {
            type: String,
            //枚举值
            enum: ['言情', '志怪', '玄幻']
        }

    });

    //2.创建模型对象 对文档操作的封装对象 
    //mongoose 会使用集合名称的复数创建集合 movie==>movies
    let BookModel = mongoose.model('movie', BookSchema);

    //3. 读取单条
    // BookModel.findOne({
    //     title: "河西"
    // }).then((res) => {
    //     console.log(res)
       
    //     mongoose.disconnect();
    // }).catch((err) => {
    //     //console.log(err)
    //     console.log('获取失败')
    // })

    // 根据id获取
    // BookModel.findById('64453f7442d5be31a5733ce4').then((res) => {
    //     console.log(res)
    //     mongoose.disconnect();
    // }).catch((err) => {
    //     //console.log(err)
    //     console.log('获取失败')
    // })

    //4.批量获取
    BookModel.find({
        price: 25
    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

});

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

三、条件控制

3.1 运算符

在mongodb不能用 >  <  >=  <=  !== 等运算符,需要使用替代符

  • >           使用         $gt

  • <           使用         $lt

  • >=         使用         $gte

  • <=         使用         $lte

  • !==        使用         $ne

    //价格小于30
    BookModel.find({
        price: {
            $lt: 30
        }
    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

3.2 逻辑运算

  • $or                逻辑或

  • $and             逻辑与

    //价格小于30
    BookModel.find({
        price: {
            $lt: 30
        }
    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

    //逻辑或
    BookModel.find({
        $or: [{price: 68},{price: 48}]
    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

    //逻辑与  大于在前,小于在后
    BookModel.find({
        $and: [{
            price: {
                $gt: 20
            }
        }, {
            price: {
                $lt: 50
            }
        }]

    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

3.3 正则匹配

条件中可以直接使用JS正则语法,通过正则可以实现模糊查询

    //正则表达式  
    BookModel.find({
        //检测title中带有‘西’
        title: /西/
    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

    BookModel.find({
        //检测title中带有‘2’
        title: new RegExp('2')
    }).then((res) => {
        console.log(res)
        mongoose.disconnect();
    }).catch((err) => {
        //console.log(err)
        console.log('获取失败')
    })

四、个性化读取

  • 字段筛选   select

  • 数据排序   sort(1/-1)    1正序,-1倒序

  • 数据截取   skip(跳过)   limit(限定)

    //字段筛选 select  title,style
    //数据排序 sort    升序是1,倒序是-1
    //数据截断 limit   
    BookModel.find().select({
            title: 1,
            style: 1
        })
        .sort({
            price: 1,
        })
        //跳过1,2,取3,4
        .skip(2)
        .limit(2)
        .then((res) => {
            console.log(res)
        }).catch((err) => {
            console.log(err)
            console.log('查询失败')
        })

五、mongoose模块化

  • config.js(配置文件)   

    • 后续需要更改的信息,如数据库地址,端口,数据库名等
//配置文件
module.exports = {
    HOST: '127.0.0.1',
    PORT: 27017,
    NAME: 'test1'
}
  • db.js(配置数据库连接)   

module.exports = function (success,error) {
    //判断 error 为其设置一个默认值
    if(typeof error !== 'function'){
        (error) => {
            console.log('连接失败');
        }
    }
    //导入mongoose
    const mongoose = require('mongoose');
    //导入配置文件
    const {HOST,PORT,NAME} = require('../config/config')

    mongoose.set('strictQuery', true);
    //连接mongodb服务                           数据库名称
    mongoose.connect(`mongodb://${HOST}:${PORT}/${NAME}`);

    mongoose.connection.once('open', () => {
        success();
    });

    //设置连接错误的回调
    mongoose.connection.on('error', () => {
        error();
    });
    //设置连接关闭
    mongoose.connection.on('close', () => {
        console.log('close')
    });
}
  • BlogModel.js(模型对象)     

    • 创建文档的结构对象,封装文档,创建模型对象,用于后续文档操作
const mongoose = require('mongoose');
//1.创建文档的结构对象 设置集合中文档的属性以及属性值的类型
let blogSchema = new mongoose.Schema({
    title: String,
    author: String,
    price: String,
    is_hot: Boolean,
    tags: [],
    pub_time: Date,
    test: mongoose.Schema.Types.Mixed,
});

// //2.创建模型对象 对文档操作的封装对象
let BlogModel = mongoose.model('Blog', blogSchema);

//暴露模型对象
module.exports = BlogModel;
  • index.js(主文件)

//导入db  函数
const db = require('./db/db')
const mongoose = require('mongoose');
//导入模型对象
const BlogModel = require('./module/BlogModel')

db((data) => {
    // //3.新增
    BlogModel.create({
        title: '路西',
        author: '呵呵呵',
        price: 34,
        is_hot: true,
        tags: ['鬼怪', '人性'],
        pub_time: new Date(),
        test: 26
    }).then((res) => {
        console.log(res)
        //4.关闭数据连接 项目运行过程中不会添加该代码
        mongoose.disconnect();
    }).catch((err) => {
        console.log(err)
    })
    console.log('success')
});
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

才不吃胡萝卜嘞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值