0. 前言:

Mongoose是NodeJS的驱动,不能作为其他语言的驱动。Mongoose有两个特点:

  • 通过关系型数据库的思想来设计非关系型数据库
  • 基于mongodb驱动,简化操作

  Mongooose中,有三个比较重要的概念,分别是Schema、Model、Document。它们的关系是:Schema生成Model,Model创造Document,Model和Document都可对数据库操作造成影响,但Model比Document更具操作性。

  Schema用于定义数据库的结构。类似创建表时的数据定义(不仅仅可以定义文档的结构和属性,还可以定义文档的实例方法、静态模型方法、复合索引等),每个Schema会映射到mongodb中的一个collection,Schema不具备操作数据库的能力。

  Model是由Schema编译而成的构造器,具有抽象属性和行为,可以对数据库进行增删查改。Model的每一个实例(instance)就是一个文档document。

  Document是由Model创建的实体,它的操作也会影响数据库。

1. 安装

在此之前需要安装nodejs和mongodb,才能使用npm来安装mongoose

npm install mongoose

项目中可使用下面的命令安装mongoose并自动将其添加到依赖

npm i mongoose --save

2. 连接数据库

2.1 首先使用 require() 引入mongoose

var mongoose = require('mongoose');

2.2 使用 connect() 来连接mongodb数据库

mongoose.connect(url);

connect()最简单的使用方式,就是只要传入url参数即可,如下所示。

/*直接连接*/
mongoose.connect("mongodb://127.0.0.1/mongoose_test" );
/*传递用户名密码来连接*/
mongoose.connect('mongodb://username:password@host:port/database?options...');

注意:mongoose版本大于或等于4.11.0时,连接数据库会提示warning(不影响运行),避免的方法添加userMongoClient的设置,且属性值为true

mongoose.connect('mongodb://数据库的ip地址:端口号/数据库名', { useMongoClient: true});

connect()方法还接受一个选项对象options,该对象将传递给底层驱动程序。

mongoose.connect(uri, options);

可用选项如下所示,更多详见参考,options 所包含的所有选项优先于连接字符串中传递的选项

 db            -数据库设置
server -服务器设置
replset -副本集设置
user -用户名
pass -密码
auth -鉴权选项
mongos -连接多个数据库

如果要连接多个数据库,只需要设置多个url以,隔开,同时设置mongos为true

mongoose.connect('urlA,urlB,...', {
mongos : true
})

connect()函数还接受一个回调参数,来判断是否连接成功

mongoose.connect(uri, options, function(error) {

});
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/mongoose_test", function(err) {
if(err){
console.log('连接失败');
}else{
console.log('连接成功');
}
});

2.3 使用 disconnect() 断开数据库连接(一般不需要调用)

MongoDB数据库,一般情况下,只需要连接一次,连接一次以后,除非项目停止服务器关闭,否则连接一般不会断开

mongoose.disconnect();

2.4 监听MongoDB数据库的连接状态

在mongoose对象中,有一个属性叫做connection,该对象表示的就是数据库连接。通过监视该对象的状态,可以来监听数据库的连接与断开

数据库连接成功的事件

mongoose.connection.once("open",function(){});

数据库断开的事件

mongoose.connection.once("close",function(){});

3. Schema

Schema主要用于定义MongoDB中集合Collection里文档document的结构。  

定义Schema需要指定字段名和类型,支持的类型包括以下9种

String      字符串
Number 数字
Date 日期
Buffer 二进制
Boolean 布尔值
Mixed 混合类型
ObjectId 对象ID
Array 数组
Decimal128 Decimal类型

通过mongoose.Schema来调用Schema,然后使用new方法来创建schema对象

var mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1/mongoose_test",{useMongoClient:true});
mongoose.connection.once("open",function () {
console.log("数据库连接成功~~~");
}); //将mongoose.Schema 赋值给一个变量
var Schema = mongoose.Schema; //创建Schema(模式)对象
var stuSchema = new Schema({
name:String,
age:Number,
gender:{
type:String,
default:"female"
},
address:String
});

[注意]创建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' });

4. Model & Document

模型Model是根据Schema编译出的构造器,或者称为类,通过Model可以实例化出文档对象document。文档document的创建和检索都需要通过模型Model来处理

mongoose.model();

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

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

实例化文档document

var StuModel = mongoose.model("student" , stuSchema);
//Document 和 集合中的文档一一对应 , Document是Model的实例 通过Model查询到结果都是Document
//创建一个Document
var stu = new StuModel({
name:"孙悟空",
age:18,
gender:"male",
address:"花果山"
});

文档保存

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

//回调函数是可选项,第一个参数为err,第二个参数为保存的文档对象
save(function (err, doc) {})
stu.save(function (err) {
if (err) return handleError(err);
})

也可减少步骤,直接向数据库插入文档

var StuModel = mongoose.model("student" , stuSchema);

//向数据库中插入一个文档
//StuModel.create(doc, function(err){});
StuModel.create({
name:"白骨精",
age:16,
address:"白骨洞"
},function (err) {
if(!err){
console.log("插入成功~~~");
}
});

结果

  

5. Model对象的方法

    

有了Model,我们就可以来对数据库进行增删改查的操作了。具体方法可参考官方文档

5.1 增加方法

Model.create(doc(s), [callback])
- 用来创建一个或多个文档并添加到数据库中
- 参数:
doc(s) 可以是一个文档对象,也可以是一个文档对象的数组
callback 当操作完成以后调用的回调函数
StuModel.create([
{
name:"沙和尚",
age:38,
gender:"male",
address:"流沙河"
} ],function (err) {
if(!err){
console.log(arguments);
}
});

控制台输出

5.2 修改方法

 Model.update(conditions, doc, [options], [callback])
Model.updateMany(conditions, doc, [options], [callback])
Model.updateOne(conditions, doc, [options], [callback])
- 用来修改一个或多个文档
- 参数:
conditions 查询条件
doc 修改后的对象
options 配置参数
callback 回调函数
Model.replaceOne(conditions, doc, [options], [callback])
StuModel.updateOne({name:"唐僧"},{$set:{age:20}},function (err) {
if(!err){
console.log("修改成功");
}
});

5.3 查询方法

Model.find(conditions, [projection], [options], [callback])
- 查询所有符合条件的文档 总会返回一个数组
Model.findById(id, [projection], [options], [callback])
- 根据文档的id属性查询文档
Model.findOne([conditions], [projection], [options], [callback])
- 查询符合条件的第一个文档 总会返回一个具体的文档对象(非数组) conditions 查询的条件
projection 投影 需要获取到的字段
- 两种方式
{name:1,_id:0}
"name -_id"
options 查询选项(skip limit)
{skip:3 , limit:1}
callback 回调函数,查询结果会通过回调函数返回
回调函数必须传,如果不传回调函数,压根不会查询

官方文档查询方法截图如下

下面分别演示几种不同的查询方法

//查询name为“唐僧”的
StuModel.find({name:"唐僧"},function (err , docs) {
if(!err){
console.log(docs);
}
});

结果

//只查询name,且不查询_id  (_id字段默认输出)
StuModel.find({},{name:1 , _id:0},function (err , docs) {
if(!err){
console.log(docs);
}
});

结果

//只查询文档的name,age值,查询时跳过3个,结果集限制只查询出一个
StuModel.find({},"name age -_id", {skip:3 , limit:1} , function (err , docs) {
if(!err){
console.log(docs);
}
});

结果

StuModel.findOne({} , function (err , doc) {
if(!err){
console.log(doc);
}
});

结果

StuModel.findById("59c4c3cf4e5483191467d392" , function (err , doc) {
if(!err){
//console.log(doc);
//通过find()查询的结果,返回的对象,就是Document,文档对象
//Document对象是Model的实例
console.log(doc instanceof StuModel);
}
});

结果

5.4 删除方法

 Model.remove(conditions, [callback])
Model.deleteOne(conditions, [callback])
Model.deleteMany(conditions, [callback])
StuModel.remove({name:"白骨精"},function (err) {
if(!err){
console.log("删除成功~~");
}
});

5.5 统计

 Model.count(conditions, [callback])
- 统计文档的数量的
StuModel.count({},function (err , count) {
if(!err){
console.log(count);
}
});

6. Document对象的方法

Document 和 集合中的文档一一对应,Document是Model的实例。通过Model查询到结果都是Document。

  

6.1 保存

save([options], [options.safe], [options.validateBeforeSave], [fn])
//创建一个Document
var stu = new StuModel({
name:"奔波霸",
age:48,
gender:"male",
address:"碧波潭"
});
//保存改document对象
stu.save(function (err,product,numAffected) { //返回三个对象 err:失败信息; product:保存的对象; numAffected:该document对象被持久化了为1,否则为0
if(!err){
    console.log("保存成功~~~");
}

6.2 更新

update(update,[options],[callback])
doc.update({$set:{age:28}},function (err) {
if(!err){
console.log("修改成功~~~");
}
});

或者对document对象进行修改,再执行save()方法

doc.age = 28;
doc.save();

6.3 删除

remove([callback])
doc.remove(function (err) {
if(!err){
console.log("删除成功~~~");
}
});

6.4 其他

get(name)
- 获取文档中的指定属性值
set(name , value)
- 设置文档的指定的属性值
id
- 获取文档的_id属性值
toJSON() ******
- 转换为一个JSON对象
toObject()
- 将Document对象转换为一个普通的JS对象【转换为普通的js对象以后,注意所有的Document对象的方法或属性都不能使用了】
console.log(doc.get("age"));
console.log(doc.age); doc.set("name","猪九戒");
doc.name = "hahaha"; console.log(doc._id);
var j = doc.toJSON();
console.log(j); var o = doc.toObject();
console.log(o); doc = doc.toObject();
delete doc.address; console.log(doc._id);

参考:

官方文档

Mongoose基础入门

尚硅谷培训课程

Mongoose使用——nodejs结合mongodb的更多相关文章

  1. nodejs操作mongodb数据库封装DB类

    这个DB类也算是我经历了3个实际项目应用的,现分享出来,有需要的请借鉴批评. 上面的注释都挺详细的,我使用到了nodejs的插件mongoose,用mongoose操作mongodb其实蛮方便的. 关 ...

  2. nodejs链接mongodb数据库

    nodeJs链接mongodb数据库有两种方式,第一种是利用官方自己开发的npm包mongodb链接,第二种是利用第三方npm包mongoose链接:这里如果是window操作系统,建议用mongoo ...

  3. nodejs实践-MongoDB

    nodejs实践-MongoDB laiqun@msn.cn Contents 1. 特点: 2. 开始使用 3. 使用Mongoose操作MongoDB 4. 在express中使用,组织数据库相关 ...

  4. Nodejs中Mongodb使用

    Mongodb使用 打开解压后的Mongodb文件夹,新建data.logs文件夹,并在logs文件夹中新建mongodb.log文档. 添加后Mongod文件夹示意图: 用cmd命令行启动Mongo ...

  5. NodeJs操作MongoDB之分页功能与常见问题

    NodeJs操作MongoDB之分页功能与常见问题 一,方法介绍 1,聚合操作之count count()方法可以查询统计符合条件的集合的总数 db.User.count(<query>) ...

  6. NodeJs操作MongoDB之多表查询($lookup)与常见问题

    NodeJs操作MongoDB之多表查询($lookup)与常见问题 一,方法介绍 aggregate()方法来对数据进行聚合操作.aggregate()方法的语法如下 1 aggregate(ope ...

  7. Mongoose轻松搞定MongoDB,不要回调!

    MEAN开发栈中使用MongoDB的时候,与之配对的ORM最好的选择就是Mongoose了.本文就和大家一起探讨一下如何使用Mongoose来实现MongoDB的增删改查. 为了能使文中的例子更加生动 ...

  8. 【重点突破】—— Nodejs+Express+MongoDB的使用基础

    前言:最近学习vue和react的高阶项目,都需要和Nodejs+Express+MongoDB结合实现全栈开发.这里结合实例Demo和所学项目集中总结一下这部分服务端的基础知识. 一.Express ...

  9. mongodb学习(2)--- nodeJS与MongoDB的交互(使用mongodb/node-mongodb-native)

    转载:http://www.cnblogs.com/zhongweiv/p/node_mongodb.html 目录 简介 MongoDB安装(windows) MongoDB基本语法和操作入门(mo ...

随机推荐

  1. 2015 UESTC 搜索专题N题 韩爷的梦 hash

    韩爷的梦 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Descrip ...

  2. 深入Delphi下的DLL编程

    深入Delphi下的DLL编程 作者:岑心 引 言 相信有些计算机知识的朋友都应该听说过“DLL”.尤其是那些使用过windows操作系统的人,都应该有过多次重装系统的“悲惨”经历——无论再怎样小心, ...

  3. Using an open debug interconnect model to simplify embedded systems design

    Using an open debug interconnect model to simplify embedded systems design Tom Cunningham, Freescale ...

  4. 介绍:一款Mathematica的替代开源软件Mathetics

    Mathetics软件 1 以Python语言实现该系统 2 软件使用的语法与Mathematica同样 3 下载:http://www.mathics.org/ 4 手冊:http://www.ma ...

  5. WINDOWS常用端口列表

    按端口号可分为3大类: (1)公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务.通常这些端口的通讯明确表明了某种服务的协议.例如:80端口实际上总 ...

  6. LaTeX排版设置图表的位置 Positioning images and tables

    Positioning images and tables LATEX is an editing tool that takes care of the format so you only hav ...

  7. ActiveMQ使用示例之Topic

    非持久的Topic消息示例  对于非持久的Topic消息的发送基本跟前面发送队列信息是一样的,只是把创建Destination的地方,由创建队列替换成创建Topic,例如: Destination d ...

  8. Unity的shader学习2

    下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情. Shade ...

  9. MYSQL错误1130:ERROR 1130: Host 10.10.36.115 is not allowed to connect to this MySQL server

    解决远程连接mysql错误1130代码的方法  在用远程连接Mysql服务器的数据库,不管怎么弄都是连接不到,错误代码是1130,ERROR 1130: Host 10.10.36.115 is no ...

  10. [Python爬虫] 之三十一:Selenium +phantomjs 利用 pyquery抓取消费主张信息

    一.介绍 本例子用Selenium +phantomjs爬取央视栏目(http://search.cctv.com/search.php?qtext=消费主张&type=video)的信息(标 ...