8.ODM框架-Mongoose

786 阅读3分钟

介绍

  • 概述:优雅的Node.js对象文档模型,Object Document Model.
  • 特点:
    • 通过关系型数据库的思想来设计的非关系型数据库
    • 基于Mongodb驱动,简化操作

安装

npm i mongoose -S

基本使用

连接数据库

//引入
const mongoose = require('mongoose');
//连接数据库
mongoose.connect('mongodb://localhost/test', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

connect() 返回一个状态待定(pending)的连接.

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', async () => {
        //连接成功的回调函数,在这里进行操作
}

定义Schema(表)

    //定义一个schema => 表
    const blogSchema = new mongoose.Schema({
        //字段
        title: String,
        author: String,
        body: String, //内容
        comments: [{ //评论
            body: String, //内容
            data: Date
        }],
        date: { //日期
            type: Date, //Date类型
            default: Date.now, //默认值
        },
        hidden: Boolean, //是否显示
        meta: { //其他字段
            votes: Number, //点击量
            favs: Number //收藏数
        }
    })

参考:更多字段类型

通过Schema创建模型(表)

const Blog = mongoose.model('Blog', blogSchema);

添加

    //先删除所有数据
    await Blog.deleteMany();
    //添加多条数据
    await Blog.insertMany([{
        title: 'Vue基础',
        author: '尤老板',
        body: 'Vue是一个轻量级的,高效的前端框架',
        comments: [{
            body: '你说的很对',
            date: new Date().toLocaleDateString()
        }],
        hidden: true,
        meta: {
            votes: 10,
            favs: 200
        }
    }, {
        title: 'React',
        author: 'faceBook',
        body: 'React是更好的前端框架',
        comments: [{
            body: '不太对,各有各的优点',
            date: new Date().toLocaleDateString()
        }],
        hidden: false,
        meta: {
            votes: 400,
            favs: 2000
        }
    }]);

查询

查询操作有find()findOne()findById()等方法.

find()

    //查询作者为‘尤老板’的数据
    let r = await Blog.find({
        author: '尤老板'
    })

find()+where()条件查询

let r = await Blog.find().where('author', '尤老板');

find()+and()多条件查询

    //查询作者为‘faceBook’并且标题为‘React’的数据
    let r = await Blog.find().and([{
        author: 'faceBook'
    }, {
        title: 'React'
    }])

删除

删除操作有remove()deleteOne()deleteMany()等方法.

remove()

    let r = await Blog.remove({
        author: '尤老板'
    })

deleteOne()

let r = await Blog.deleteOne({
        author: '尤老板'
    })

更新

更新操作有update()updateOne()updateMany()等方法.

    let r = await Blog.update({
        author: '尤老板'
    }, {
        author: '雨老板'
    })

Schema对象定义实例方法、静态方法和虚拟属性

Tips:定义需要在定义Schema对象之后,并且在创建模型之前.

实例方法

定义之后可直接通过new出来的实例b调用findAuthor()方法.

    //定义实例方法(schema对象上的方法),需要先获取模型
    blogSchema.methods.findAuthor = function () {
        //model()中填写 ‘模型名’
        return this.model('Blog').find({
            author: this.author
        }).exec();
    }
    
    //使用
    let b = new Blog({
        author: '尤老板'
    });
    //需要通过new 出来的模型实例调用
    let r = await b.findAuthor();
    console.log(r);

静态方法

    //定义静态方法(模型上的方法)
    blogSchema.statics.findTitle = function (title) {
        //内部的 this 指向的就是模型,可以直接调用 find() 方法
        return this.find({
            title: title
        }).exec();
    }
    
    //使用
    //直接通过模型对象调用
    r = await Blog.findTitle('React');
    console.log(r);

虚拟属性

虚拟属性用于查询操作返回后的对象,且如果返回的是一个数组,则需要单独获取到每一个具体的对象之后才能调用.

    //定义虚拟属性
    blogSchema.virtual('getContent').get(function () {
        return `${this.author}发布了文章${this.title}`;
    })
    
    //使用
    //根据 id 查询,先获取id并转换成 mongodb中的 id 对象
    let id = mongoose.Types.ObjectId('5fafe2f208fcce1f44c4f9e3');
    let r = await Blog.findOne({
        '_id': id
    });
    //直接通过返回的 r 对象调用属性,若返回的是数组,则需要获取到每个单独的对象
    console.log(r.getContent);