记录 MongoDB/Mongoose

132 阅读6分钟

首先确保你已安装 MongoDB 和 Node.js
Mongoose中文文档 入门 - Mongoose 中文网 (nodejs.cn)

下载:

npm install mongoose --save

使用

连接数据库

import mongoose from 'mongoose';

const url = 'mongodb://localhost:27017';// 连接本地数据库
const options = {  // 连接配置
  dbName: 'test', // 设置数据库名称
  // user: 'myUserName',// 设置用户名
  // pass: 'myPassword',// 设置密码
  // mongos: true, // 使用MongoDB多服务器连接
  serverSelectionTimeoutMS: 1000, // 设置服务器选择超时时间,单位为毫秒,默认为30秒
  autoIndex: false, // 禁用自动索引
}
// 连接到MongoDB数据库
const connectDB = async () => {
  try {
    await mongoose.connect(url, options);
    console.log('MongoDB 连接成功');
  } catch (error) {
    console.error('"MongoDB 连接失败:', error);
  }
};
connectDB() //启动

创建模型

import mongoose from 'mongoose';

// 创建模型
// 通过Schema创建Model
// Model 代表的是数据库中的集合,通过Model才能对数据库进行操作,Model是由Schema生成的
const TestSchema = new mongoose.Schema({
  // 当未定义_id字段时 mongoose 会为每一个文档自动添加一个不重复的_id,
  // 类型为ObiectId(在查询语句中需要通过 findById() 方法来查询)
  name: {
    type: String,
    required: true,// 必填
    // default: '默认值', // 默认值
    // select: false, // 是否显示该字段,默认为true
    // alias: '别名', // 字段别名
    // get: (v: any) => { return v + '后缀' }, // 自定义获取器
    // set: (v: any) => { return v + '前缀' }, // 自定义设置器
    // transform: (v: any) => { return v.toUpperCase() }, // 自定义转换器
    // index: true, // 是否对这个属性创建索引
    // unique: true, // 是否对这个属性创建唯一索引
    // sparse: true, // 是否对这个属性创建稀疏索引

    // trim: true, // 去除字符串两端的空格 仅字符串类型可用
    // lowercase: true, // 转换为小写 仅字符串类型可用
    // uppercase: true, // 转换为大写 仅字符串类型可用

  },
  age: { type: Number, required: true, },
  PersonId:{
      type: Schema.Types.ObjectId, 
      ref: 'Person' // 关联Person表
  },
  gender: String,

}, { timestamps: true }); // timestamps 时间戳

//映射 
// 参数: 要映射的集合名,创建的约束(Schema对象)
const Test = mongoose.model('Test', TestSchema);

增加数据

Model.create()

  • 用法:
    • 该方法用于创建并保存一个或多个文档。它可以接受一个对象或一个对象数组作为参数。
    • 当传入单个对象时,Model.create() 相当于 new Model().save() 的快捷方式。
    • 当传入一个对象数组时,Model.create() 会创建并保存多个文档。
  • 优点:
    • 语法简洁,将创建和保存操作合并为一个步骤。
    • 适合创建和保存少量文档的场景。
const createTest = async () => { //创建数据
  try {
    await Test.create({name:"小明",age: 18,gender:'男'},{name:"小红",age: 18,gender:"女"})
    console.log('数据保存成功');
  } catch (error) {
    console.log('数据保存失败:', error);
  }
}
createTest()

Model.save() 推荐使用

  • 用法:
    • 该方法用于保存一个已经通过 new Model() 实例化的文档到数据库中。
    • 你首先需要使用 new Model() 创建一个文档实例,然后调用 .save() 方法来保存它。
  • 优点:
    • 允许在保存之前对文档进行更多的操作或验证。
    • 更适合需要在保存前对文档进行操作(如修改或计算)的场景。
const createTest = async () => { //创建数据
  try {
    const test = new Test({name:"小明",age: 18,gender:'男'},{name:"小红",age: 18,gender:"女"});
    await test.save();
    console.log('数据保存成功');
  } catch (error) {
    console.log('数据保存失败:', error);
  }
}
createTest()

Model.insertMany()

  • 用法:
    • 该方法用于一次性插入多个文档到数据库中。
    • 它可以接受一个对象数组作为参数,直接将这些对象插入到数据库中。
  • 优点:
    • 处理大量文档时性能更高,因为它在内部使用 MongoDB 的 insertMany 操作,这比逐个保存文档的方式要快得多。
    • 适合批量插入文档的场景。
const createTest = async () => { //创建数据
  try {
    wait Test.insertMany([{name:"小明",age: 18,gender:'男'},{name:"小红",age: 18,gender:"女"}]);
    console.log('数据保存成功');
  } catch (error) {
    console.log('数据保存失败:', error);
  }
}
createTest()

image.png

修改数据

Model.updateOne() 、 Model.findOneAndUpdate() 根据条件,更新一条数据

const updateTest = async () => { //更新数据
  try {
    // const test = await Test.updateOne({ name: '张三' }, { name: '李四' }); // 更新name为张三的第一条符合的数据数据
     // const test = await Test.findOneAndUpdate({ name: '李四' }, { name: '张三三' }, { new: true }); // 更新name为张三的的第一条符数据,并返回更新后的数据
     const test = await Test.findOneAndUpdate({ name: '张三' }, { name: '张三三' }, { new: true, upsert: true }); // 更新name为张三的的第一条符数据,如果不存在则创建
  } catch (error) {
    console.log('更新失败:', error)
  }
}
updateTest()

Model.findByIdAndUpdate() 根据id更新数据

   const id = '66c5ac8df60b20a84d442751'; // 张三的id,自己在数据库查询
   const test = await Test.findByIdAndUpdate(id, { name: '李四' }, { new: true });

Model.updateMany() 更新符合条件的所有数据

const test = await Test.updateMany({name:'张三'},{name:'李四',age:80}) //更新name为张三的数据
const updateTest = async () => { //更新数据
 try {
    // const test = await Test.updateOne({ name: '张三' }, { name: '李四' }); // 更新name为张三的第一条符合的数据
    // const test = await Test.findOneAndUpdate({ name: '李四' }, { name: '张三三' }, { new: true }); // 更新name为张三的的第一条符数据,并返回更新后的数据
    // const test = await Test.findOneAndUpdate({ name: '张三' }, { name: '张三三' }, { new: true, upsert: true }); // 更新name为张三的的第一条符数据,如果不存在则创建

    // const id = '66c5ac8df60b20a84d442751'; // 张三的id,自己在数据库查询
    // const test = await Test.findByIdAndUpdate(id, { name: '李四' }, { new: true });

    const test = await Test.updateMany({name:'张三'},{name:'李四',age:80}) //更新name为张三的数据 更新符合条件的所有数据
    console.log('更新成功:', test);
  } catch (error) {
    console.log('更新失败:', error)
  }
}
updateTest()

image.png

image.png

查询数据

普通查询

  • Model.find(conditions, [projection], [options], [callback]);
  • Model.findById(id, [projection], [options], [callback]);
  • Model.findOne([conditions], [projection], [options], [callback]);
const findTest = async () => { //查询数据
  try {
    // const tests = await Test.find({ name: '张三' }); // 查询name为张三的数据
    // const tests = await Test.findById({_id:'66c6a85b92d3452830e294d9'}); // 查询指定id的数据
    // const tests = await Test.findOne({ name: '张三' }); // 查询第一条name为张三的数据
    // const tests = await Test.countDocuments(); // 查询数据条数

    // const tests = await Test.find() //查询全部数据
    // .where('name').regex('张') // 模糊查询
    // .gt(18) // 大于18
    // .gte(18) // 大于等于18
    // .lt(20) // 小于20
    // .lte(20) // 小于等于20
    // .select('name age') // 查询指定字段 只返回name和age字段
    // .sort({ age: -1 }) // 排序 -1降序 1升序
    // .limit(20) // 限制返回条数
    // .skip(2) // 跳过条数
    // .populate('PersonId') // 关联查询Person集合 返回关联的Person集合数据
    // .exec(); // 执行查询

    // 分页查询
    const pageSize = 10, pageNumber = 1 
    const totalCount = await Test.countDocuments().exec();//获取总数
    const tests = await Test.find().skip(((pageNumber as number) - 1) * (pageSize as number)).limit(pageSize as number).exec();//获取分页数据
   
    console.log('查询结果:', tests);
  } catch (error) {
    console.log('查询失败:', error);
  }
}
findTest()

删除数据

Model.deleteOne() , Model.findOneAndDelete() 删除第一条符合的数据

const deleteTest = async () => { //删除数据
  try {
    // const test = await Test.deleteOne({ name: '张三' }); // 删除name为张三的第一条符合的数据

    // const test = await Test.findOneAndDelete({ name: '张三'}) // 删除第一条符合的数据

    console.log('删除成功:', test);
  } catch (error) {
    console.log('删除失败:', error);
  }
}
deleteTest()

Model.findByIdAndDelete() 按id删除数据

const deleteTest = async () => { //删除数据
  try {
    const id = '66c5ac8df60b20a84d442751';
    const test = await Test.findByIdAndDelete(id); // 删除指定id的数据
    console.log('删除成功:', test);
  } catch (error) {
    console.log('删除失败:', error);
  }
}
deleteTest()

Model.deleteMany() 删除所有符合条件的数据

const deleteTest = async () => { //删除数据
  try {
    // const test = await Test.deleteMany({ age: 18 }); // 删除name为张三的所有数据
    console.log('删除成功:', test);
  } catch (error) {
    console.log('删除失败:', error);
  }
}
 deleteTest()
const deleteTest = async () => { //删除数据
  try {
    // const test = await Test.deleteOne({ name: '张三' }); // 删除name为张三的第一条符合的数据


    // const test = await Test.deleteMany({ age: 18 }); // 删除name为张三的所有数据

    // const test = await Test.findOneAndDelete() // 删除第一条符合的数据

     const id = '66c5ac8df60b20a84d442751';
     const test = await Test.findByIdAndDelete(id); // 删除指定id的数据
    console.log('删除成功:', test);
  } catch (error) {
    console.log('删除失败:', error);
  }
}
deleteTest()

image.png