Node.js中的Mongoose实用笔记

本文详细介绍了Node.js中使用Mongoose操作MongoDB的相关知识,包括Mongoose的基本概念、安装、数据库连接、模型定义、文档操作、中间件、验证及错误处理等,帮助开发者更好地理解和使用Mongoose。
摘要由CSDN通过智能技术生成

mongoose官网  http://mongoosejs.com/

1.Mongoose学习参考文档

前言:本学习参考文档仅供参考,如有问题,师请雅正

##一、快速通道

###1.1 名词解释

  • Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力

  • Model : 由Schema发布生成的模型,具有抽象属性和行为的数据库操作对

  • Entity : 由Model创建的实体,他的操作也会影响数据库

注意

1.本学习文档采用严格命名方式来区别不同对象,例如:

    var PersonSchema;   //Person的文本属性
    var PersonModel;    //Person的数据库模型
    var PersonEntity;   //Person实体

2.SchemaModelEntity的关系请牢记,Schema生成ModelModel创造EntityModelEntity都可对数据库操作造成影响,但ModelEntity更具操作性。

##1.2 准备工作

1.首先你必须安装MongoDBNodeJS

2.在项目只能够创建一个数据库连接,如下:

    var mongoose = require('mongoose');    //引用mongoose模块
    var db = mongoose.createConnection('localhost','test'); //创建一个数据库连接

3.打开本机localhosttest数据库时,我们可以监测是否有异常

    db.on('error',console.error.bind(console,'连接错误:'));
    db.once('open',function(){
    
      //一次打开记录
    });

注意

成功开启数据库后,就可以执行数据库相应操作,假设以下代码都在回调中处理

4.定义一个Schema

    var PersonSchema = new mongoose.Schema({
    
      name:String   //定义一个属性name,类型为String
    });

5.将该Schema发布为Model

    var PersonModel = db.model('Person',PersonSchema);
    //如果该Model已经发布,则可以直接通过名字索引到,如下:
    //var PersonModel = db.model('Person');
    //如果没有发布,上一段代码将会异常

6.用Model创建Entity

    var personEntity = new PersonModel({
    name:'Krouky'});
    //打印这个实体的名字看看
    console.log(personEntity.name); //Krouky

7.我们甚至可以为此Schema创建方法

    //为Schema模型追加speak方法
    PersonSchema.methos.speak = function(){
    
      console.log('我的名字叫'+this.name);
    }
    var PersonModel = db.model('Person',PersonSchema);
    var personEntity = new PersonModel({
    name:'Krouky'});
    personEntity.speak();//我的名字叫Krouky

8.Entity是具有具体的数据库操作CRUD

    personEntity.save();  //执行完成后,数据库就有该数据了

9.如果要执行查询,需要依赖Model,当然Entity也是可以做到的

    PersonModel.find(function(err,persons){
    
      //查询到的所有person
    });

注意

1. 具体的如何配置SchemaModel以及ModelEntity的相关操作,我们会在后面进行

2. ModelEntity都有能影响数据库的操作,但仍有区别,后面我们也会做解释

##二、新手指引

如果您还不清楚Mongoose是如何工作的,请参看第一章快速通道快速浏览他的用法吧

###1. Schema——纯洁的数据库原型

####1.1 什么是Schema

  • 我理解Schema仅仅只是一断代码,他书写完成后程序依然无法使用,更无法通往数据库端
  • 他仅仅只是数据库模型在程序片段中的一种表现,或者是数据属性模型

####1.2 如何定义Schema

    var BlogSchema = new Schema({
    
      title:String,
      author:String
      //new Schema()中传入一个JSON对象,该对象形如 xxx:yyyy ,
      /xxx是一个字符串,定义了属性,yyy是一个Schema.Type,定义了属性类型
    });

####1.3 什么是Schema.Type

Schema.Type是由Mongoose内定的一些数据类型,基本数据类型都在其中,他也内置了一些Mongoose特有的Schema.Type。当然,你也可以自定义Schema.Type,只有满足Schema.Type的类型才能定义在Schema内。

####1.4 Schema.Types

NodeJS中的基本数据类型都属于Schema.Type,另外Mongoose还定义了自己的类型

    //举例:
    var ExampleSchema = new Schema({
    
      name:String,
      binary:Buffer,
      living:Boolean,
      updated:Date,
      age:Number,
      mixed:Schema.Types.Mixed, //该混合类型等同于nested
      _id:Schema.Types.ObjectId,  //主键
      _fk:Schema.Types.ObjectId,  //外键
      array:[],
      arrOfString:[String],
      arrOfNumber:[Number],
      arrOfDate:[Date],
      arrOfBuffer:[Buffer],
      arrOfBoolean:[Boolean],
      arrOfMixed:[Schema.Types.Mixed],
      arrOfObjectId:[Schema.Types.ObjectId]
      nested:{
    
        stuff:String,
      }
    });

####1.5 关于Buffer

BufferArrayBufferNodejs两种隐藏的对象,相关内容请查看NodeJS-API

####1.6 关于Mixed

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

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

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

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

####1.7 关于ObjectId

主键,一种特殊而且非常重要的类型,每个Schema都会默认配置这个属性,属性名为_id,除非自己定义,方可覆盖

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

该类型的值由系统自己生成,从某种意义上几乎不会重复,生成过程比较复杂,有兴趣的朋友可以查看源码。

####1.8 关于Array

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

    var ExampleSchema1 = new Schema({
    array:[]});
    var ExampleSchema2 = new Schema({
    array:Array});
    var ExampleSchema3 = new Schema({
    array:[Schema.Types.Mixed]});
    var ExampleSchema4 = new Schema({
    array:[{}]});

####1.9 附言

Schema不仅定义了文档结构使用性能,还可以有扩展插件实例方法静态方法复合索引文档生命周期钩子

Schema可以定义插件,并且插件具有良好的可拔插性,请有兴趣的读者继续往后阅读或者查阅官方资料。

###2. Schema的扩展

####2.1 实例方法

有的时候,我们创造的Schema不仅要为后面的ModelEntity提供公共的属性,还要提供公共的方法。

下面例子比快速通道的例子更加高级,可以进行高级扩展:

    var PersonSchema = new Schema({
    name:String,type:String});
    //查询类似数据
    PersonSchema.methods.findSimilarTypes = function(cb){
    
      return this.model('Person').find({
    type:this.type},cb);
    }

使用如下:

    var PersonModel = mongoose.model('Person',PersonSchema);
    var krouky = new PersonSchema({
    name:'krouky',type:'前端工程师'});
    krouky.findSimilarTypes(function(err,persons){
    
      //persons中就能查询到其他前端工程师
    });

####2.2 静态方法

静态方法在Model层就能使用,如下:

  PersonSchema.statics.findByName = function(name,cb){
    
    this.find({
    name:new RegExp(name,'i'),cb});
  }
  var PersonModel = mongoose.model('Person',PersonSchema);
  PersonModel.findByName('krouky',function(err,persons){
    
    //找到所有名字叫krouky的人
  });

####2.3 索引

索引或者复合索引能让搜索更加高效,默认索引就是主键索引ObjectId,属性名为_id索引会作为一个专题来讲解

####2.4 虚拟属性

Schema中如果定义了虚拟属性,那么该属性将不写入数据库,例如:

    var PersonSchema = new Schema({
    
      name:{
    
        first:String,
        last:String
      }
    });
    var PersonModel = mongoose.model('Person',PersonSchema);
    var krouky = new PersonModel({
    
      name:{
    first:'krouky',last:'han'}
    });

如果每次想使用全名就得这样

    console.log(krouky.name.first + ' ' + krouky.name.last);

显然这是很麻烦的,我们可以定义虚拟属性

    PersonSchema.virtual('name.full').get(function(){
    
      return this.name.first + ' ' + this.name.last;
    });

那么就能用krouky.name.full来调用全名了,反之如果知道full,也可以反解firstlast属性

    PersonSchema.virtual('name.full').set(function(name){
    
      var split = name.split(' ');
      this.name.first = split[0];
      this.name.last = split[1];
    });
    var PersonModel = mongoose.model('Person',PersonSchema);
    var krouky = new PersonModel({});
    krouky.name.full = 'krouky han';//会被自动分解
    console.log(krouky.name.first);//krouky

####2.5 配置项

在使用new Schema(config)时,我们可以追加一个参数options来配置Schema的配置,形如:

    var ExampleSchema = new Schema(config,options);

或者使用

    var ExampleSchema = new Schema(config);
    ExampleSchema.set(option,value);

可供配置项有:safestrictcappedversionKeyautoIndex

#####2.5.1 safe——安全属性(默认安全)

一般可做如下配置:

    new Schema({...},{
    safe:true});

当然我们也可以这样

    new Schema({...},{
    safe:{
    j:1,w
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值