操作 MongoDB

MongoDB

MongoDB 是一个基于分布式文件存储的数据库

相比较纯文件管理数据有如下特点特点

  • 速度快
  • 扩展性强
  • 安全性强

三个核心概念:

  • 数据库(database):数据库是一个数据仓库,可以创建很多数据库
  • 集合(collection):集合位于数据库之中,在集合中可以存放很多文件
  • 文档(document):文档是数据库中的最小单位,类似于 js 中的对象

使用 Mongoose

  • mongoose 是一个可以通过 node 来操作 mongodb 的包
  • mongoose 是一个对象文档模型库,对 node 原生的 mongodb 进行了封装,提供了更多功能。
  • mongoose 中的对象:
    • Schema 模式对象,约束了数据库中的文档结构
    • Model 模型对象,作为集合中的所有文档表示,相当于 mongodb 数据库中的结合 collection
    • Document 文档对象,表示集合中的具体文档,相当于集合中的一个具体文档

mongoose的好处

  1. 可以为文档创建一个模式结构
  2. 可以对模型中的对象/文档进行验证
  3. 数据可以通过类型转换转换为对象模型
  4. 可以使用中间件来应用业务逻辑挂钩
  5. 比Node原生的MongoDB驱动更容易

连接数据库

// config/db.config.js
const mongoose = require('mongoose')

mongoose.connect('mongodb://127.0.0.1:27017/stu')

mongoose.connection.once('open',() => {
    console.log('连接成功')
})

mongoose.connection.on('error',() => {
    console.log('连接错误')
})

mongoose.connection.on('close',() => {
    console.log('连接断开')
})
// 断开数据库连接
mongoose.disconnect()

在 bin 目录下的 www 文件中直接使用 require('../config/cdb.config.js') 进行数据库的连接启动

创建模式对象和模型对象

数据库中的 Schema 是数据库的对象的集合,可以简单理解为表;每个 schema 会映射到 mongodb 中的 collection。
字段类型

类型 作用
String 定义字符串
Number 定义数字
Date 定义日期
Buffer 定义二进制
Boolean 定义布尔值
Mixed 定义混合类型
ObjectId 定义对象ID
Array 定义数组
// model/BookModels

const mongoose = require('mongoose')

const BookSchema = mongoose.Schema({
    name: { type: String, require: true }, // 名称 unique: true必须唯一 不可以重复 不可以为空
    author: { type: String, default: '匿名' }, // 作者 默认值
    price: { type: Number, require: true },
    _isHot: { type: Boolean, enum: [true, false] },
    tags: Array,
    data: { type: Date, require: true }
})

// 第一个参数表示创建的集合的名称,第二个参数表示利用的模式对象(第三个参数是强行指定集合名称)
const BookModles = mongoose.models('books',BookSchema)

module.export = BookModles

注意:

mongoose 支持 es6,在我自己操作时,如果使用了回调函数形式的方法来进行数据库操作,会报错,以 save()为例:

MongooseError: Model.prototype.save() no longer accepts a callback

所以我下面使用的是 es6 的方式进行 mongoose 的使用

新增文档(三种)

save()

  • 操作文档
const mongoose = require('mongoose')
const BookModel = require('../model/BookModel')

// 链式调用
    BookModel({
        name: '西游记7',
        author: '吴承恩',
        price: 72.75,
        _isHot: true,
        tags: ['社会', '恐怖', '晚上不要看'],
        data: new Date()
    }).save().then(data => {
        console.log(data)
    }).catch(err=>{
        console.log(err)
    })

create()

  • 操作模型
    BookModel.create({
        name: '西游记2',
        author: '吴承恩',
        price: 72.75,
        _isHot: true,
        tags: ['社会', '恐怖', '晚上不要看'],
        data: new Date()
    }).then(data => {
        console.log(data)
    })

insertMany()

    BookModel.insertMany(
        [{
            name: '西游记12',
            author: '吴承恩',
            price: 72.75,
            _isHot: true,
            tags: ['社会', '恐怖', '晚上不要看'],
            data: new Date()
        },
        {
            name: '西游记13',
            author: '吴承恩',
            price: 72.75,
            _isHot: true,
            tags: ['社会', '恐怖', '晚上不要看'],
            data: new Date()
        }]
    ).then(data=>console.log('data',data))

文档查询

_id name price ···· __ v
645af6a79964b2ec38f406a9 西游记 19.9 ···· 0
645af6a79964b2ec38f406aa 红楼梦 29.9 ···· 0
645af6a79964b2ec38f406ab 三国演义 25.9 ···· 0
645af6a79964b2ec38f406ac 水浒传 20.9 ···· 0

find()

BookModel.find({price: 25.9}).then(data=>console.log(data));

findById()

BookModel.findById('645af6a79964b2ec38f406aa').then(data=>console.log(data));

findOne()

  • 返回查询到的数据的第一个
BookModel.findOne({name: '西游记'}).then(data => {console.log(data)});

条件查询 $where

BookModel.find({$where : "/^西游记/.test(this.name)"}).then(data=>console.log(data)).catch(err=>console.log(err))

其他常用查询条件

BookModel.find({ price: { $lt: 20 } }, { id: 0 }).then(data => { console.log(data) });

BookModel.find({ $or: [{ price: { $lt: 20 } }, { price: { $gt: 70 } }] }).then(data => { console.log(data) });

BookModel.find({ $and: [{ price: { $gt: 20 } }, { price: { $lt: 70 } }] }).then(data => { console.log(data) });

BookModel.find({name:/^西/}).then(data=>console.log(data));

BookModel.find({name:new RegExp('西')}).then(data=>console.log(data));

特定类型查询

    BookModel.find({ $and: [{ price: { $gt: 20 } }, { price: { $lt: 70 } }] })
        .select({ author: 1, price: 1, _id: 0 }) // 1为要显示的值,0为不显示的值
        .then((data) => console.log(data))
        .catch((err) => console.error(err));

    BookModel.find({ $and: [{ price: { $gt: 20 } }, { price: { $lt: 70 } }] })
        .select({ author: 1, price: 1, _id: 0 })
        .sort({ price: 1 }) // 1 升序,-1 降序
        .then((data) => console.log(data))
        .catch((err) => console.error(err));

    BookModel.find({ $and: [{ price: { $gt: 20 } }, { price: { $lt: 70 } }] })
        .select({ author: 1, price: 1, _id: 0 })
        .sort({ price: 1 }) // 1 升序,-1 降序
        .skip(2) // 跳过两个
        .limit(5) // 截取五个
        .then((data) => console.log(data))
        .catch((err) => console.error(err));

文档更新

updateOne

  • 只更新符合条件的第一条
BookModel.updateOne({name:'西游记'},{price: 7.5}).then(data=>{console.log(data)});

updateMany

  • 更新符合条件的每一条
BookModel.updateMany({_isHot: true},{price: 100}).then(data=>{console.log(data)});

文档删除

deleteOne

  • 删除符合条件的第一条
    BookModel.deleteOne({_id:'645af6a79964b2ec38f406a9'}).then(data=>{
        console.log(data);
    });

deleteMany

  • 删除符合条件的每一条
    BookModel.deleteMany({_isHot:true}).then(data=>{
        console.log(data);
    });

findOneAndRemove()

  • 找到并删除符合条件的第一条
    BookModel.findOneAndRemove({_isHot: true}).then(data=>{console.log(data)})

前后钩子

  • 前后钩子 pre 和 post 方法,是中间件
  • 在 schema 上指定
  • 在执行一些操作时设置前后钩子
  • pre():在执行操作前执行,需要使用 next() 继续下一步操作
  • pre():在执行操作后执行,不可以使用 next()
// 这些钩子需要在 Schema 的实例对象上挂载
let BookSchema = mongoose.Schema({
    // 省略
})
BookSchema.pre('find',(next)=>{
    console.log('pre被执行')
    next()
})
BookSchema.post('find',(data)=>{
    console.log('post被执行',data) 
})
posted @ 2023-05-18 10:28  超重了  阅读(67)  评论(0编辑  收藏  举报