一、mongoose 介绍

  • Mongoose 是在 nodeJs 异步环境下对 mongodb 进行便捷操作的对象模型工具。
  • Mongoose 是 NodeJS 的驱动,不能作为其他语言的驱动。
  • Mongoose 有两个特点
    • 1、通过关系型数据库的思想来设计非关系型数据库
    • 2、基于 mongodb 驱动,简化操作
二、mongoose 的安装以及使用

1. 安装

npm i mongoose --save复制代码

2、引入 mongoose 并连接数据库

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test'); 
如果有账户密码需要采用下面的连接方式: 
mongoose.connect('mongodb://eggadmin:123456@localhost:27017/eggcms'); 
复制代码

3、定义 Schema

数据库中的 Schema,为数据库对象的集合。schema 是 mongoose 里会用到的一种数据模式, 可以理解为表结构的定义;每个 schema 会映射到 mongodb 中的一个 collection,它不具备 操作数据库的能力

var UserSchema=mongoose.Schema({ name: String, age:Number, status:'number' })复制代码

4、创建数据模型

定义好了 Schema,接下就是生成 Model。model 是由 schema 生成的模型,可以对数据库的 操作。

注意:

  • mongoose.model 里面可以传入两个参数也可以传入三个参数
  • mongoose.model(参数 1:模型名称(首字母大写),参数 2:Schema)
  • mongoose.model(参数 1:模型名称(首字母大写),参数 2:Schema,参数 3:数据库集合名称)
  • 如果传入 2 个参数的话,这个模型会和模型名称相同的复数的数据库建立连接:如通过下面 方法创建模型,那么这个模型将会操作 users 这个集合。
var UserModel=mongoose.model('User', UserSchema); 
复制代码
  • 如果传入 3 个参数的话:模型默认操作第三个参数定义的集合名称
var UserModel=mongoose.model('User', UserSchema, 'users'); 
复制代码

5、查找数据

UserModel.find({}, function(err, docs) {  if (err) {console.log(err);return;
  }  console.log(docs);
});复制代码

6、增加数据

//实例化模型 传入增加的数据var u = new UserModel({  name: "lisi2222",  age: 20,  status: true});
u.save();复制代码

7、修改数据

UserModel.updateOne({ name: "lisi2222" }, { name: "哈哈哈" }, function(err, res) {  if (err) {console.log(err);return;
  }  console.log("成功");
});复制代码

8、删除数据

UserModel.deleteOne({ _id: "5b72ada84e284f0acc8d318a" }, function(err) {  if (err) {console.log(err);return;
  } 
  //只会删除一条
  console.log("成功");
});复制代码

9、保存成功后查找

var u = new UserModel({  name: "lisi2222333",  age: 20,  status: true //类型转换});
u.save(function(err, docs) {  if (err) {console.log(err);return;
  } 
  //console.log(docs);
  UserModel.find({}, function(err, docs) {if (err) {      console.log(err);      return;
    }console.log(docs);
  });
});复制代码
三、mongoose 模块化

由于所有数据库操作都是基于schema生成的模型(Model),为了免去所有用到的地方都生成Model的麻烦,将其封装,在使用到的地方引入即可。

1、封装

项目目录创建models目录

/*
models/db.js
连接数据库
*/var mongoose = require("mongoose");//useNewUrlParser这个属性会在url里识别验证用户所需的db,未升级前是不需要指定的,升级到一定要指定。mongoose.connect(  "mongodb://usersDB_readwrite:123456@localhost:27017/newsDB",
  { useNewUrlParser: true, useUnifiedTopology: true },  function (err) {if (err) {      console.log(err);      return;
    }console.log("数据库连接成功");
  }
);module.exports = mongoose;复制代码
/*
models/userModel.js
用户表model
*/var mongoose = require("./db.js");var UserSchema = mongoose.Schema(
  {account: { type: String, trim: true }, // 账号password: { type: String, trim: true }, // 密码username: { type: String, trim: true }, // 名称email: String, // 邮箱avatar: String, // 头像profile: String, // 简介
  },
  { versionKey: false }
);var userModel = mongoose.model("User", UserSchema, "users");module.exports = userModel;复制代码

2、使用

/*
routes/user.js
此处演示express中使用,其它框架一样。
1、引入
2、调用
*/var express = require("express");// 引入userModelvar UserModel = require("../models/userModel");var Result = require("../common/Result");var router = express.Router();// 注册接口router.post("/regist", function (req, res, next) {  //用接收到的注册参数实例化模型
  let newUser = new UserModel(req.body);  //调用save保存
  newUser.save(function (err) {if (err) {      console.log(err);      return;
    }
    res.json(200, new Result({ msg: "新用户保存成功" }));
  });
});复制代码
四、Mongoose 修饰符

1、预定义模式修饰符

mongoose 提供的预定义模式修饰符,可以对我们增加的数据进行一些格式化。

var UserSchema = mongoose.Schema({  name: { type: String, trim: true },  age: Number,  status: { type: Number, default: 1 }
});复制代码
  • String
  • Number
  • Date
  • Buffer
  • Boolean
  • Mixed
  • ObjectId
  • Array
  • Decimal128

详细介绍

1、自定义修饰符(get & set)

除了 mongoose 内置的修饰符以外,我们还可以通过 set(建议使用) 修饰符在增加数据的 时候对数据进行格式化。也可以通过 get(不建议使用)在实例获取数据的时候对数据进行格式化。

// Demovar NewsSchema = mongoose.Schema({  title: "string",  author: String,  pic: String,  redirect: {type: String,set: function(url) {      if (!url) return url;      // 写入时前缀补全 (会改变数据)  if (url.indexOf("http://") != 0 && url.indexOf("https://") != 0) {
        url = "http://" + url;
      }      return url;
    },get: function(url) {      if (!url) return url;      // 读取时前缀补全 (不会改变数据)  if (url.indexOf("http://") != 0 && url.indexOf("https://") != 0) {
        url = "http://" + url;
      }      return url;
    }
  },  content: String,  status: { type: Number, default: 1 }
});复制代码
五、Mongoose 索引

索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更 快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询 优化技巧。

var DeviceSchema = new mongoose.Schema({  sn: {type: Number, // 唯一索引unique: true
  },  name: {type: String, // 普通索引index: true
  }
});复制代码
六、Mongoose CURD

1、 内置CURD

  • Model.deleteMany()
  • Model.deleteOne()
  • Model.find()
  • Model.findById()
  • Model.findByIdAndDelete()
  • Model.findByIdAndRemove()
  • Model.findByIdAndUpdate()
  • Model.findOne()
  • Model.findOneAndDelete()
  • Model.findOneAndRemove()
  • Model.findOneAndUpdate()
  • Model.replaceOne()
  • Model.updateMany()
  • Model.updateOne()

2、 拓展CURD

var UserSchema=mongoose.Schema({name:{type:String       
    },sn:{type:String,index:true},age:Number,       status:{type:Number,default:1}
})//静态方法 UserSchema.statics.findBySn=function(sn,callback){//通过 find方法获取 sn的数据    this 关键字获取当前的modelthis.find({"sn":sn},function(err,docs){
        callback(err,docs)
    })   
}// 实例方法   (基本不用)UserSchema.methods.print=function(){console.log('我是一个实例方法')console.log(this.name)
}复制代码
// 自定义静态方法UserModel.findBySn('123456782',function(err,docs){if(err){console.log(err);return;
    }console.log(docs)
})var user = new UserModel({name: '赵六',sn:'123456781',age: 29});//自定义的实例方法user.print();复制代码
七、多表关联查询

1、aggregate

mongoDB aggregate 聚合管道

var mongoose = require("./db.js");var OrderSchema = mongoose.Schema({  order_id: String,  uid: Number,  trade_no: String,  all_price: Number,  all_num: Number});var OrderModel = mongoose.model("Order", OrderSchema, "order");
OrderModel.aggregate(
  [
    {      $lookup: {from: "order_item",localField: "order_id",foreignField: "order_id",as: "item"  }
    }
  ],  function(err, docs) {// order表关联order_itm表,将order_item的数据赋值给item一并返回console.log(docs);
  }
);复制代码

三个表关联查询Mongoose入门_Mongoose

 ArticleModel.aggregate([
  {$lookup: {      from: "articlecate",      localField: "cid",      foreignField: "_id",      as: "cate"}
  },
  {$lookup: {      from: "user",      localField: "author_id",      foreignField: "_id",      as: "user"}
  }

],function(err,docs){  console.log(JSON.stringify(docs));
})复制代码

2、populate 关联查询

Mongoose入门_Mongoose

var mongoose=require('./db.js');var ArticleSchema = mongoose.Schema({title:{ type: String, unique: true     
    },cid : { type: Schema.Types.ObjectId,   ref:"ArticleCate"    //cid和 文章分类建立关系。(model名称)   },   /*分类 id*/author_id:{        type: Schema.Types.ObjectId ,ref:"User"    //author_id和 用户表建立关系。(model名称)},   /*用户的id*/author_name:{        type:String      
    },descripton:String,   content   : String});module.exports=mongoose.model('Article',ArticleSchema,'article');复制代码
//注意使用 populate需要引入用到的modelvar ArticleCateModel=require('./model/articlecate.js');var ArticleModel=require('./model/article.js');var UserModel=require('./model/user.js');//文章表和 分类表的关联ArticleModel.find({}).populate('cid').exec(function(err,docs){	console.log(docs);
})//三个表关联ArticleModel.find({}).populate('cid').populate('author_id').exec(function(err,docs){	console.log(docs);
})复制代码

建议使用管道方式关联查询(aggregate)