3.3 Mongoose的Schema、modle、document

Schema

我理解Schema仅仅只是一断代码,他书写完成后程序依然无法使用,更无法通往数据库端,他仅仅只是数据库模型在程序片段中的一种表现,或者是数据属性模型,Schema主要用于定义MongoDB中集合Collection里文档document的结构类型。

// schema 是一个数据结构的范式 
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var mySchema = new Schema({
  title:  String,
  author: String,
  body:   String,
  comments: [{ body: String, date: Date }],
  date: { type: Date, default: Date.now },
  hidden: Boolean,
  meta: {
    votes: Number,
    favs:  Number
  }
});

types

  • String 字符串

  • Number 数字

  • Date 日期

  • Buffer 二进制

  • Boolean 布尔值

  • Mixed 混合类型

  • ObjectId 对象ID 主键

  • Array 数组

  • _fk:Schema.Types.ObjectId, //外键

  • [String] 数组[Number],[Date],[Buffer],[Boolean],Schema.Types.Mixed],[Schema.Types.ObjectId]

[注意]创建Schema对象时,声明字段类型有两种方法,一种是首字母大写的字段类型,另一种是引号包含的小写字段类型

var mySchema = new Schema({title:String, author:String});
//或者 
var mySchema = new Schema({title:'string', author:'string'});

如果需要在Schema定义后添加其他字段,可以使用add()方法

var MySchema = new Schema;
MySchema.add({ name: 'string', color: 'string', price: 'number' });

timestamps

在schema中设置timestamps为true,schema映射的文档document会自动添加createdAt和updatedAt这两个字段,代表创建时间和更新时间

var UserSchema = new Schema(
  {...},
  { timestamps: true }
);

_id

每一个文档document都会被mongoose添加一个不重复的_id,_id的数据类型不是字符串,而是ObjectID类型。如果在查询语句中要使用_id,则需要使用findById语句,而不能使用find或findOne语句

    const mongoose = require('mongoose');
    const ObjectId = mongoose.Schema.Types.ObjectId;
    const StudentSchema = new Schema({}); //默认会有_id:ObjectId
    const TeacherSchema = new Schema({id:ObjectId});//只有id:ObjectId

Array

ArrayJavaScript编程语言中并不是数组,而是集合,因此里面可以存入不同的值,以下代码等价:

    const Schema1 = new Schema({array:[]});
    const Schema2 = new Schema({array:Array});
    const Schema3 = new Schema({array:[Schema.Types.Mixed]});
    const Schema4 = new Schema({array:[{}]});

Mixed

Schema.Types.MixedMongoose定义个混合类型,该混合类型如果未定义具体形式。因此,如果定义具体内容,就直接使用{}来定义,以下两句等价

    const AnySchema = new Schema({any:{}});
    const AnySchema = new Schema({any:Schema.Types.Mixed});

混合类型因为没有特定约束,因此可以任意修改,一旦修改了原型,则必须调用markModified()

    person.anything = {x:[3,4,{y:'change'}]}
    person.markModified('anything');//传入anything,表示该属性类型发生变化
    person.save();

预定义模式修饰符

在配置Schema的时候使用,

  • trim 自动去掉空格 前后

  • UpperCase

  • lowerCase

自定义模式修饰符

还可以使用GettersSetters 来进行处理

  • setters 将在数据进入数据库前的时候对数据进行加工 (强烈建议使用)包括查询 插入更新 删除都会触发这个方法

  • getters 将在数据获取的时候对数据进行加工 (不建议使用)因为只有实体才能使用这个

const UserSchema = new Schema({
    username:{
        type:String,
        required:true,
        set(params){ //进行格式处理
            // 添加数据的时候对username这个字段进行处理
            //set 函数要求 必须返回一个值 
            //返回的 值则是真正储存在数据库中的值
            //set  函数不允许异步
        },
        get(){//这个方法是在获取实例数据的时候对数据进行格式化
            //const user =new UserModel({})
            //user.find() 
            //只有在user  实例上才能触发这个方法   所以几乎不用

        }
    }
})

getter 和setter 函数在nodejs 中本质上不允许异步

设置索引

Schema 初始化可以给表字段增加索引

// 普通索引
const UserSchema = new Schema({
    username:{
        type:String,
        required:true,
        index:true,//设置成普通索引
        unique:true //唯一索引
    }
})
  1. 旨在需要的时候对字段设置索引

  2. 所以会导致表空间变大

  3. 会导致增加变慢

Model

Model模型,是经过Schema构造来的,除了Schema定义的数据库骨架以外,还具有数据库行为模型,他相当于管理数据库属性、行为的类,通过Model可以实例化出文档对象document,文档document的创建和检索都需要通过模型Model来处理

model()

mongoose.model()

使用model()方法,将Schema编译为Model.model()方法的第一个参数是模型名称

[注意]一定要将model()方法的第一个参数和其返回值设置为相同的值,否则会出现不可预知的结果

Mongoose会将集合名称设置为模型名称的小写版。如果名称的最后一个字符是字母,则会变成复数;如果名称的最后一个字符是数字,则不变;如果模型名称为"MyModel",则集合名称为"mymodels";如果模型名称为"Model1",则集合名称为"model1"

var schema = new mongoose.Schema({ num:Number, name: String, size: String});
var MyModel = mongoose.model('MyModel', schema);
var tank = {name:'zhangsan',num:1,size:'large'};
    MyModel.create(tank);

你可以使用Model来创建EntityEntity实体是一个特有Model具体对象,但是他并不具备Model的方法,只能用自己的方法。

  //通过Model创建Entity
  var tankEntity = new TankModel('someother','size:big');
  tankEntity.save();

实例化文档document(entiry)

通过对原型Model1使用new方法,实例化出文档document对象

var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {
    if(err){
        console.log('连接失败');
    }else{
        console.log('连接成功');
        var schema = new mongoose.Schema({ num:Number, name: String, size: String});
        var MyModel = mongoose.model('MyModel', schema);
        var doc1 = new MyModel({ size: 'small' });
        console.log(doc1.size);//'small'
    }
});

文档保存

通过new Model1()创建的文档doc1,必须通过save()方法,才能将创建的文档保存到数据库的集合中,集合名称为模型名称的小写复数版

回调函数是可选项,第一个参数为err,第二个参数为保存的文档对象

save(function (err, doc) {})
var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:123456@localhost/db1", function(err) {
    if(!err){
        var schema = new mongoose.Schema({ num:Number, name: String, size: String });
        var MyModel = mongoose.model('MyModel', schema);
        var doc1 = new MyModel({ size: 'small' });
        doc1.save(function (err,doc) {
        //{ __v: 0, size: 'small', _id: 5970daba61162662b45a24a1 }
          console.log(doc);
        })
    }
});

Last updated

Was this helpful?