Node.js开发——MongoDB与Mongoose
为了保存网站的用户数据和业务数据,通常需要一个数据库。MongoDB和Node.js特别般配,因为MongoDB是基于文档的非关系型数据库,文档是按BSON(JSON的轻量化二进制格式)存储的,增删改查等管理数据库的命令和JavaScript语法很像。
我也准备使用MongoDB来作为我的数据库。
MongoDB使用集合(collection)和文档(document)来描述和存储数据,collection就相当于表,document相当于行,不过MySQL之类的关系型数据库,表结构是固定的,比如某一行由若干列组成,行行都一样,而MongoDB不同,一个集合里的多个文档可以有不同的结构,更灵活一些。
安装
详细指南在这里:https://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/。
到 https://www.mongodb.org/downloads
下载安装包,Windows系统是msi文件,我选择的是“Windows 64-bit 2008 R2+”这个版本。
安装非常简单,你可以默认,也可以选择安装位置,我装到了G盘MongoDB目录下。安装完后,目录结构是这样的:G:\MongoDB\Server\3.0\。
mongod、mongo以及其它的工具,都在3.0目录下的bin目录。
启动
要使用MongoDB,需要指定一个文件夹让它存放数据,我在G:\MongoDB下建立了一个名为db的文件夹。
打开cmd,进入G:\MongoDB\Server\3.0\bin目录,执行“mongod –dbpath='G:\MongoDB\db'”,就会启动MongoDB,看到下面的图:
MongoDB启动后,会监听在一个端口上等待客户端来连接,从上图可以看出,默认监听的端口是27017。你可以“–port”选项改变这个端口,比如“mongod –port 28018 –dbpath=G:\MongoDB\db
”命令就会启动MongoDB并监听28018端口。
启动了MongoDB,我们就可以使用mongo(交互式shell)来管理数据库了。直接在bin目录下执行mongo,就可以看到下图(需要新开一个窗口):
mongo Shell默认连接到了test数据库,还告诉我们可以输入help来查看帮助。你可以键入help并回车,看看都有哪些命令可用。
注意,mongod默认启动时不带鉴权,客户端连上后就可以随便操作,建库、增删改查等统统可以。你要想限制用户权限,可以自己配置下,我这里就直接往下走了。
数据库管理
新建数据库
MongoDB的shell没有提供新建数据库的功能,不过你可以这样:
use accounts
db.createCollection('accounts')
当你使用“use accounts”切换到名为accounts的数据库时,实际上什么也没发生,只有当你调用了db.createCollection之后,新的数据库才被保存,然后你使用“show dbs”就可以看到新建的库。
删除数据库
删除数据库需要切换到指定的库,然后调用dropDatabase()。如下:
use accounts
db.dropDatabase()
调用dropDatabase之后,可以使用“show dbs”查看。
创建集合
之前新建数据库时已用到,调用createCollection即可。
显示集合
这样:
use accounts
show collections
获取指定名字的集合
要得到集合对象,可以这样:
use accounts
coll = db.getCollection("accounts")
删除集合
要删除集合,需要调用集合对象的drop()方法。这样:
use accounts
coll = db.getCollection("accounts")
coll.drop();
向集合中添加文档
要把文档添加到集合,需要先得到collection对象,然后调用insert(document)方法。document参数是一个JSON对象。下面的命令往accounts集合里添加了两个用户:
use accounts
coll = db.getCollection("accounts")
coll.insert({name:"ZhangSan",password:"123456"})
coll.insert({name:"WangEr",password:"nicai"})
在集合中查找
使用集合对象的find()方法,可以列出集合里的所有文档。这样:
use accounts
coll = db.getCollection("accounts")
coll.find()
带参数的find()方法可以根据某个字段来查找:
coll.find({name:"ZhangSan"})
从集合中删除文档
使用collection对象的remove(object)方法可以删除文档。它的参数是JS对象,它通过将你传入对象的属性与数据库内数据比对来匹配某一个文档,匹配到后删除,匹配不上就拉倒。假如你传递一个空的JS对象,就会删除这个集合里所有的文档。比如下面这样:
use accounts
coll = db.getCollection("accounts")
coll.insert({name:"QianQi",password:"888888"})
coll.find()
coll.remove({name:"WangEr"})
coll.find()
coll.remove({})
coll.find()
更新集合中的文档
collection对象提供了两种方法来更新文档:save(object)和update(query, update, options)。
save可以直接更新一个对象,下面的代码将ZhangSan的密码修改为567890:
coll.save({_id:ObjectId("55cc25b360bcee730bafd2bf"),name:"ZhangSan",password:"567890"})
下面的update方法与上面的save效果一样:
coll.update({name:"ZhangSan"},{name:"ZhangSan",password:"567890"})
update()的第二个参数update是一个对象,能指定更新时用的运算符,比如$set
可以设置字段的值,下面代码与前面等效:
coll.update({name:"ZhangSan"},{$set: {password:"567890"}});
使用mongoose管理数据库
Node.js有针对MongoDB的数据库驱动:mongodb。你可以使用“npm install mongodb”来安装。
不过直接使用mongodb模块虽然强大而灵活,但有些繁琐,我就使用mongoose吧。如果你对原始的驱动模块感兴趣,可以从这里开始:https://docs.mongodb.org/getting-started/node/client/。
mongoose构建在mongodb之上,提供了Schema、Model和Document对象,用起来更为方便。
我们可以用Schema对象定义文档的结构(类似表结构),可以定义字段和类型、唯一性、索引和验证。Model对象表示集合中的所有文档。Document对象作为集合中的单个文档的表示。mongoose还有Query和Aggregate对象,Query实现查询,Aggregate实现聚合。
关于这些的信息,可以看这里:http://mongoosejs.com/docs/guide.html。
废话不多说,看看怎么使用吧。
安装mongoose
使用express准备一个TestMongoDB项目,命令序列如下:
express TestMongoDB
cd TestMongoDB
npm install
执行完上面的命令后,使用下面的命令安装mongoose:
npm install mongoose --save
这个命令会安装mongoose并将其作为项目的依赖,而mongoose依赖的MongoDB driver以及regexp等等模块也会被自动安装。
使用mongoose
建议先看mongoose官方的quick start教程:
http://mongoosejs.com/docs/index.html。
讲得很到位,虽然是E文,也很容易理解,读之有如荒漠遇甘泉。
为了理解用到的API,看这里:http://mongoosejs.com/docs/api.html。
API看起来有点
使用mongoose可以新建数据库、新建集合、对集合内的文档进行CRUD操作,在写代码时,可以对照着mongo shell验证结果是否符合预期。
在TestMongoDB下新建一个mongo.js文件,内容如下:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/accounts');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('mongoose opened!');
var userSchema = new mongoose.Schema({
name:{type: String, unique: true},
password:String
},
{collection: "accounts"}
);
var User = mongoose.model('accounts', userSchema);
User.findOne({name:"WangEr"}, function(err, doc){
if(err) console.log(err);
else console.log(doc.name + ", password - " + doc.password);
});
var lisi = new User({name:"LiSi", password:"123456"});
lisi.save(function(err, doc){
if(err)console.log(err);
else console.log(doc.name + ' saved');
});
});
上面的文件,直接执行“node mongo.js”命令即可查看效果。
要使用mongoose,先require,然后使用connect方法连接数据库。connect原型:
connect(uri, options, [callback])
uri的格式类似:“mongodb://user:pass@localhost:port/database”。
mongoose的connection对象定义了一些事件,比如connected、open、close、error等,我们可以监听这些事件。
在我们的示例代码里,我监听了open事件,在回调函数中,定义了Schema,调用mongoose.model来编译Schema得到Model对象。需要注意的是,定义Schema时指定的collection名字与mongoose.model的第一参数要保持一致。
拿到了Model对象,就可以执行增删改查等操作了。Model对象有find()、findOne()、update()、remove()等方法,和我们在mongo shell里的用法类似。这些方法都有一个可选的callback,当你提供这些callback时,执行的结果会通过这个callback返回给你。如果你不提供,这些方法会返回一个Query对象,你可以再通过Query组装新的选项,然后调用Query的exec(callback)来提交查询。
我在代码里查找WangEr的档案时用了callback,没用Query。
Model对象有个Model(doc)方法,用来构造一个文档(Document)。创建Lisi的文档时就是这种Document对象的save()方法可以将文档保存到数据库。
Mongoose就说这么多吧,很多详细的用法,用到时参考API文档吧,多数API都提供有示例代码片段。
Node.js开发——MongoDB与Mongoose的更多相关文章
- node.js开发错误——DeprecationWarning: Mongoose: mpromise
原文地址 使用mongoose进行数据库操作时,总是提示: (node:5684) DeprecationWarning: Mongoose: mpromise (mongoose's default ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)
这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...
- 以太坊开发DApp实战教程——用区块链、星际文件系统(IPFS)、Node.js和MongoDB来构建电商平台(一)
第一节 简介 欢迎和我们一起来用以太坊开发构建一个去中心化电商DApp!我们将用区块链.星际文件系统(IPFS).Node.js和MongoDB来构建电商平台类似淘宝的在线电商应用,卖家可以自由地出售 ...
- Node.js +Express+MongoDB+mogoose+ejs+bootstrap+jquery
Node.js + MongoDB 项目实战(二) 创建项目 在项目实战(一)中,已经配置好了开发环境(详见:http://www.cnblogs.com/jameslong/articles/34 ...
- Node.js开发Web后台服务
一.简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.j ...
- 学习Nodejs:《Node.js开发指南》微博项目express2迁移至express4过程中填的坑
<Node.js开发指南>项目地址https://github.com/BYVoid/microblog好不容易找到的基础版教程,但书中是基于express2的,而现在用的是express ...
- iKcamp新书上市《Koa与Node.js开发实战》
内容摘要 Node.js 10已经进入LTS时代!其应用场景已经从脚手架.辅助前端开发(如SSR.PWA等)扩展到API中间层.代理层及专业的后端开发.Node.js在企业Web开发领域也日渐成熟,无 ...
- Node.js 开发技能图谱
# Node.js 开发技能图谱 ## Node.js 语言环境搭建 - Node.js 安装(3m大法:nvm.npm.nrm)- Node.js 命令- Node.js开发工具(推荐vscode) ...
- Node.js学习笔记——Node.js开发Web后台服务
一.简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.j ...
随机推荐
- java 线程 获取当前线程
java 线程 获取当前线程 Thread th=Thread.currentThread(); System.out.println("Tread name:"+th.getNa ...
- [译文]casperjs使用说明-选择器
casperjs的选择器可以在dom下工作,他既支持css也支持xpath. 下面所有的例子都基于这段html代码: <!doctype html> <html> <he ...
- python为何需要虚拟环境--Python虚拟环境的安装和配置-virtualenv
一 虚拟环境 virtual environment 它是一个虚拟化,从电脑独立开辟出来的环境.通俗的来讲,虚拟环境就是借助虚拟机docker来把一部分内容独立出来,我们把这部分独立出来的东西称作“容 ...
- 2016级算法第五次上机-E.AlvinZH的学霸养成记IV
1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...
- python学习,day3:函数式编程,带return
return的主要作用就是,在调用的时候,能知道函数的运行情况,相当于打个标签 # coding=utf-8 # Author: RyAn Bi def test1(): print('in the ...
- Keras中间层输出的两种方式,即特征图可视化
训练好的模型,想要输入中间层的特征图,有两种方式: 1. 通过model.get_layer的方式.创建新的模型,输出为你要的层的名字. 创建模型,debug状态可以看到模型中,base_model/ ...
- Sklearn,TensorFlow,keras模型保存与读取
一.sklearn模型保存与读取 1.保存 from sklearn.externals import joblib from sklearn import svm X = [[0, 0], [1, ...
- Little Sub and Piggybank (杭师大第十二届校赛G题) DP
题目传送门 题意:每天能往存钱罐加任意实数的钱,每天不能多于起那一天放的钱数.如果某一天的钱数恰好等于那天的特价商品,则可以买,求最后的最大快乐值. 思路:先来一段来自出题人的题解: 显然的贪心:如果 ...
- 3. Javascript学习笔记——变量、内存、作用域
3. 变量.内存.作用域 3.1 基本类型和引用类型的值 ECMAScript 变量可能包含两种不同数据类型的值:基本类型值[Undefined.Null.Boolean.Number 和 Strin ...
- 【Python】端口扫描脚本
0x00 使用模块简介 1.optparse模块 选项分析器,可用来生成脚本使用说明文档,基本使用如下: import optparse #程序使用说明 usage="%prog -H ...