mongoose

anch / 2024-03-19 / 原文

  • 挖坑:集合CURD,文档CURD

  • [ 数据库连接 ]
    • 连接一个不存在的数据库,不会立即创建该数据库,只有执行到文档对象的 save 等方法时,才会去创建该数据库
      const mongoose = require('mongoose')
      // 这里捕获的是链接过程中发生的异常
      const db = mongoose.connect('mongodb://host:port/dbname').catch(err => console.log(err))
    
      // 安全模式链接数据库,user 和 pwd 分别是用户名和密码
      const db = mongoose.conect('mongodb://user:pwd@host:port/dbname').catch(err => console.log(err))
    
      // 这里使用 once 而不是 on,只有第一次 open 的时候输出
      db.once('open', ()=> {console.log('database connect successful')})
    
      // 链接成功以后如果出现异常,处理异常
      db.on('error', err => console.log(err))
    

  • [ Schema ]
    • 一般来说,数据验证应该在操作数据库之前就完成,可以使用 express-validator 中间件实现提前验证。
    • 结构支持的预设 type 类型:
    • https://mongoose.nodejs.cn/docs/schematypes.html#google_vignette
      • String | 专有类型选项 ,
      • Number | 专有类型选项 ,
      • Date | 专有类型选项 ,
      • Buffer ,
      • Boolean ,
      • Mixed ,
      • ObjectId | 专有类型选项 ,
      • Array ,
      • Decimal128,
      • Map ,
      • Schema,
      • UUID ,
      • BigIng

  • [ 通用模式类型选项 ]
    • https://mongoose.nodejs.cn/docs/schematypes.html#schematype-options
      required,
      default,
      select, // 返回文档对象的时候是否返回该属性,password一般不会返回,所以设置为 false
      validate(val),
      get(),
      set(val),
      alias('realname', 'name'), // realname 会被写入数据库,name 是其别名,用来简化代码,name 也可以是一个字符串数组,用来设置多个别名
      immutable, // Boolean, 为 true 时,该属性不允许被更改,更改操作会失效,除非设置文档对象的 isNew 属性为 true
      transform(), 将schema 转化为 json,一般不主动使用
    

  • [ model ]
    • 通过 schema 创建 model
      // 数据库会将 User 自动转换为 users,在数据库中创建 users 集合
      const User = mongoose.model('User', userSchema)
    
    • 通过 model 对象生成文档对象
      const user01 = new User({...})
      // or
      const user02 = User.create({...})
    
    • 文档增删改查的静态方法

  • [ 文档查询 ]
    • find
      // find all documents
      await MyModel.find({});
    
      // find all documents named john and at least 18
      await MyModel.find({ name: 'john', age: { $gte: 18 } }).exec();
    
      // executes, name LIKE john and only selecting the "name" and "friends" fields
      await MyModel.find({ name: /john/i }, 'name friends').exec();
    
      // passing options
      await MyModel.find({ name: /john/i }, null, { skip: 10 }).exec();
    
    • findById
      // Find the adventure with the given `id`, or `null` if not found
      await Adventure.findById(id).exec();
    
      // select only the adventures name and length
      await Adventure.findById(id, 'name length').exec();
    
    • findOne
      // Find one adventure whose `country` is 'Croatia', otherwise `null`
      await Adventure.findOne({ country: 'Croatia' }).exec();
    
      // Model.findOne() no longer accepts a callback
    
      // Select only the adventures name and length
      await Adventure.findOne({ country: 'Croatia' }, 'name length').exec();
    
    • where
      User
      .where('age').gte(21).lte(65)
      .where('name', /^b/i)
      ... etc
    

  • [ 删除 通过模型对象删除匹配到的文档对象 ]
    • User.deleteOne(filter)
    • User.deleteMany(filter)

  • [ 更新 通过模型对象更新匹配到的文档对象 ]
    • User.updateOne(filter, update) 不会返回文档对象
    • User.findOneAndUpdate(filter, update) 会返回文档对象

  • [ 文档对象 ]
    • save()
      doc.name = 'foo';
    
      // Mongoose sends an `updateOne({ _id: doc._id }, { $set: { name: 'foo' } })`
      // to MongoDB.
      await doc.save();
    

  • [ 高级查询处理 ]
    • aggregate
    • 实例