关键词:mongodb安装 mongoose使用 robomongo mongoose的CRUD操做 mongoose的查询,增长,修改,删除html
MongoDBnode
MongoDB是基于Javascript语言的数据库,存储格式是JSON,而Node也是基于JavaScript的环境(库),因此node和mongoDB的搭配能减小由于数据转换带来的时间空间开销。mysql
Mongoosegit
是MongoDB的一个对象模型工具,它将数据库中的数据转换为JavaScript对象以供你在应用中使用,封装了MongoDB对文档的的一些增删改查等经常使用方法,让NodeJS操做Mongodb数据库变得更加灵活简单。github
Robomongosql
一个可视化的mongoDB操做软件,相似于mysql的navicat可视化工具。mongodb
捋一捋它们的关系,mongoDB是一个数据库,mongoose是你在本身代码中操做mongo数据库的接口,而robomongo是mongo数据库的可视化工具,经过它的界面方便直接操做数据库内容。数据库
1.安装mongoDBexpress
到官网https://www.mongodb.com/download-center#community下载程序安装,选择custom模式就行。npm
2.创建MongoDB环境
须要本身创建db目录做为数据库环境,在命令行窗口中输入
$ md \data\db
创建db文件夹后,在命令窗口中进入安装目录的bin文件夹执行mongod.exe,把数据库安装在datadb中。mongoDB会检测你的根目录是否有datadb文件夹,若是有会默认安装到这个文件夹里面。
$ cd C:\Program Files\MongoDB\Server\3.2\bin $ mongod.exe
固然也能够直接在系统根目录下建立datadb文件夹,而后在mongoDB安装文件夹中双击执行mongod.exe。
3.启动MongoDB
命令行工具中输入:
$ cd C:\Program Files\MongoDB\Server\3.2\bin $ mongod.exe
为了不每次都要输入目录,因此在系统变量里面配置一下path变量,把";C:Program FilesMongoDBServer3.2bin"放到path后面(记得加;隔开),之后能够直接在命令行窗口输入mongod.exe回车便可。
在浏览器中输入网址:http://localhost:27017/ 。若是服务启动成功会看到如下一段话:It looks like you are trying to access MongoDB over HTTP on the native driver port.
4.链接MongoDB(这一步基本没有用,只有在命令行工具中使用mongo原生方法时须要,而在mongoose里面会有链接的代码,Robomongo运行也会有链接)
命令行工具中输入mongo.exe,回车。
若是出现这个警告:2016-07-16T14:49:02.827+0800 I CONTROL [main] Hotfix KB2731284 or later update is not installed, will zero-out data files那是由于Windows缺乏一个补丁,从这个连接下周补丁451413_intl_x64_zip,而后解压安装包,在你解压的目录下找到Windows6.1-KB2731284-v3-x64.mus安装文件。安装重启便可。
直接到官网https://robomongo.org/下载安装,安装成功后运行,第一次运行,须要新建立一个链接,如图建立test,点击save保存链接。
选择test,点击connect链接数据库。robomongo会本身搜索你系统里面安装的mongodb并与其链接。如图
链接成功后,显示你的数据库,在这个节目能够对数据库进行操做。如图:
首先假定你已经安装了 Node.js,命令行工具输入:
$ npm install mongoose -g
在使用的文件中require("mongoose");便可。
Mongose基于mongodb的原生方法,本身定义了一套操做MongoDB数据库的接口,比原生方法更加简单方便。为了更加直观,下面的步骤结合例子来说。假如我须要作一个教务系统,须要存储学生Student的信息,学生信息一般包含姓名name,学号id,电话phone,登陆日期date等。我把学生的信息存在mongodb的myDB数据库中,集合的名字叫students。如图:
_id这个域你能够本身定义,但若是你没有定义,系统会自动给你加上。下面先介绍在node中经过mongoose对mongodb进行操做的必须前提步骤:
1.node链接数据库
mongoose.connect('mongodb://user:pass@ip:port/database');
这只是最基本的链接,咱们通常还会加一些设置,是否开启调试模式,链接提示等。一般我会这么写:
var mongoose = require("mongoose"); mongoose.Promise = global.Promise; /*调试模式是mongoose提供的一个很是实用的功能,用于查看mongoose模块对mongodb操做的日志,通常开发时会打开此功能,以便更好的了解和优化对mongodb的操做。*/ mongoose.set('debug', true); /*通常默认没有user和password*/ var db=mongoose.connect('mongodb://localhost/myDB'); db.connection.on("error", function (error) { console.log("数据库链接失败:" + error); }); db.connection.on("open", function () { console.log("数据库链接成功"); });
没有mongoose.Promise = global.Promise会出现以下错误(这个错误没有什么影响):
意思是mongoose自带的promise过时了,而后须要使用v8引擎的promise。
2.定义模式(Schema)
每一个模式映射mongoDB的一个集合(注意映射这个词,下面会讲为何),它定义(只是定义,不是实现)这个集合里面文档的结构,就是定义这个文档有什么字段,字段类型是什么,字段默认值是什么等。除了定义结构外,还定义文档的实例方法,静态模型方法,复合索引,中间件等。详情本身查看mongoose官方文档。
var mongoose = require('mongoose'); var Schema = mongoose.Schema; /*定义模式Student_Schema*/ var Student_Schema = new Schema({ name: String, id: Number, phone: String, date: Date }, { versionKey: false }); /*定义模型Student,注意数据库存的是students*/ mongoose.model("Student", Student_Schema);
{versionKey: false}是干吗用?若是不加这个设置,咱们经过mongoose第一次建立某个集合时,它会给这个集合设定一个versionKey属性值,这个属性值包含这个文档的内部版本,数据库中显示为_v,如图:
经过{versionKey: false}能够配置这个参数,让数据库再也不添加这个属性,格式是:new Schema({..}, { versionKey: false });
3.定义模型(Model)
模型用来实现咱们定义的模式,调用mongoose.model来编译Schema获得Model。
/*定义模型Student,数据库存的是students*/ mongoose.model("Student", Student_Schema);
为何上面我强调模式的映射,那是由于模式仅仅是和db中集合文档的结构相对应(映射),它并不直接在数据库中操做这个结构,模型才是直接与数据库打交道的存在,能够这么说:模式是定义结构,模型是实现操做。当咱们使用mongoose.model("Student", Student_Schema)建立Student模型对数据进行操做时,数据库会寻找一个名字叫students集合接受Student模型的操做,特别须要注意的是:1.若是是增长(instance.save)操做时,数据库中没有这个集合,数据库会自动建立这个集合存储数据,这个集合产生规则为:把Model名字字母所有变小写和在后面加复数s。2.若是是删改查三个操做数据库中没有这个集合,那就是没有,删除空修改空返回空。
4.访问模型
var MyStudent = mongoose.model("Student");
到这里,已经基本完成了使用mongoose前提操做了。有没有以为有点繁琐,其实我也以为挺繁琐,幸运的是234能够一步建立:
var MyStudent = mongoose.model('Student',{ name: String, id: Number, phone: String, date: Date });
5.建立实例(instance)
var sam = new MyStudent({ name: "sam976", id: 123, phone: "18706888888", date: Date.now() });
通常只在save(增长)操做中须要。
模型的实例是集合中真实的数据,就是collection中的document,用mysql中的术语来讲就是一条记录。模型在数据库中建好了集合和文档结构后,经过实例往里面添加真实的document。
捋一捋模式、模型、实例的关系:模式定义了操做和属性,这些操做和属性包括mongoose自带和自定义,而模型和实例能够对模式里面定义的属性和方法进行引用。模型是mongoose用来和数据库直接打交道的中介,实例是往数据库存的真实数据。模式并不是必须,那为何要分开模式和模型呢?我以为是遵循了软件设计中“定义和实现分开”这个原则。有的文章说模式没有操做数据库的能力,模型才有,对这个观点,我以为部分对,虽然说模式不能直接操做数据库,但模式定义的方法能够被模型用来操做数据库。官方文档是这么说的:
Schemas not only define the structure of your document and casting of properties, they also define document instance methods, static Model methods, compound indexes and document lifecycle hooks called middleware.
以上是使用mongoose进行增删查改操做都须要通过的前提步骤,下面正式介绍对数据库的增删查改(CRUD)操做。
1.CRUD之create
使用模型建立sam实例,sam实例调用save方法把document存入数据库的students集合中,代码以下
var MyStudent = mongoose.model("Student"); var sam = new MyStudent({ name: "sam976", id: 123, phone: "18706888888", date: Date.now() }); sam.save(function(err) {});
经过robomongo查看数据库,能够看到数据已经存放成功,如图
2.CRUD之read
使用MyStudent模型调用find()方法返回students集合的全部内容,第一个参数定义条件,第二个参数是回调函数,回调函数中的docs是返回的是查找结果,结果形式为一个json数据数组[{},{}]。
var MyStudent = mongoose.model("Student"); MyStudent.find({}, function(err, docs) {});
好比数据库students集合中,有以下数据:
运行上面代码,结果console.log输出显示以下:
模型还能够调用其余不少查询的函数,好比
Model.findById(id, [projection], [options], [callback]); Model.findOne([conditions], [projection], [options], [callback]);
篇幅较多,这里不摊开来说(之后会专门出一篇介绍),能够本身查看官方文档关于Querying介绍
3.CRUD之update
使用MyStudent模型调用update()方法完成更新,第一个参数是条件(也就是where name="sam976"),第二个参数修改的内容。
var MyStudent = mongoose.model("Student"); MyStudent.update({name:"sam976"},{id:456,phone:"12345678910"}, function(error){});
运行如上代码前,如图
运行如上代码后,如图
4.CRUD之delete
使用MyStudent模型调用remove()方法删除文档。
var MyStudent = mongoose.model("Student"); MyStudent.remove({ name: 'sam976' }, function (err) {});
使用mongoose的时候,一般会在项目中建立三个文件:connect.js,mongoose-db.js,app.js。
其中connect.js存放的是链接数据库的操做,咱们只须要加载一次便可在程序运行期间一直链接数据库。
mongoose-db.js文件存放模式和模型的生成的代码,没有链接信息,也没有其余额外不相干代码,能够在在mongoose-db.js中把模型exports公开:
var MyStudent = mongoose.model("Student", Student_Schema); exports.MyStudent=MyStudent; /*定义其余模型和模式*/ var MyTeacher = mongoose.model("Teacher", Teacher_Schema); exports.MyTeacher=MyTeacher;
而后在app.js中引用:
var MyStudent = require("./mongoose-db").MyStudent; var MyTeacher = require("./mongoose-db").MyTeacher;
app.js存放对数据库的操做,好比CRUD。经过这样的方式,结构比较清晰,代码可读性大大加强。
下面放源码(目的是给本身备份,笑脸...)
connect.js
var mongoose = require("mongoose"); mongoose.Promise = global.Promise;//为了解决过时的问题 /*调试模式是mongoose提供的一个很是实用的功能,用于查看mongoose模块对mongodb操做的日志,通常开发时会打开此功能,以便更好的了解和优化对mongodb的操做。*/ mongoose.set('debug', true); /*mongoose会缓存命令,只要connect成功,处于其前其后的命令都会被执行,connect命令也就无所谓放哪里*/ var db=mongoose.connect('mongodb://localhost/myDB'); db.connection.on("error", function (error) { console.log("数据库链接失败:" + error); }); db.connection.on("open", function () { console.log("数据库链接成功");
mongoose-db.js
require('./connect'); var mongoose = require('mongoose'); var Schema = mongoose.Schema; /*定义模式Student_Schema*/ var Student_Schema = new Schema({ name: String, id: Number, phone: String, date: Date }, { versionKey: false }); /*定义模型Student,数据库存的是students*/ var MyStudent = mongoose.model("Student", Student_Schema); exports.MyStudent=MyStudent; /*mongoose.Schema({ username: {// 真实姓名 type: String, required: true }, password: { // 密码 type: String, required: true } });*/
app.js
require("./mongoose-db"); var express = require("express"); var mongoose = require("mongoose"); var MyStudent = require("./mongoose-db").MyStudent; var app = express(); app.use(express.static("./")); app.get("/create", function(req, res) { console.log("create 函数") var beta = new MyStudent({ name: "beta", id: 124, phone: "1871111111", date: Date.now() }); beta.save(function(err) { if (err) { console.log(err); } else { console.log('存入成功'); } }); res.send("存入成功!!"); }); app.get("/read", function(req, res) { console.log("读取函数"); MyStudent.find({}, function(err, docs) { console.log(docs); /*对docs进行操做*/ }); res.send("读取成功!!"); }); app.get("/readOne", function(req, res) { console.log("读取单值函数"); MyStudent.findOne({ name: req.query.student_name }, { "id": 1, "_id": 0 }, function(err, docs) { if (docs.id === req.query.student_id) { res.send('登陆成功'); console.log(docs.password); } else { console.log(docs.password); res.send('登陆失败'); } }); /*过滤查询,参数2: {'name':1, 'password':0} 查询文档的返回结果包含name , 不包含password.(_id默认是1)*/ /*model.find({},null,{limit:20});过滤查询,参数3: 游标操做 limit限制返回结果数量为20个,如不足20个则返回全部*/ }); app.get("/update", function(req, res) { console.log("更新函数"); MyStudent.update({ name: "sam976" }, { id: 456, phone: "12345678910" }, function(error) {}); res.send("更新成功!!"); }); app.get("/delete", function(req, res) { console.log("删除函数"); MyStudent.remove({ name: 'sam976' }, function(err) { if (err) return handleError(err); // removed! }); res.send("删除成功!!"); }); app.listen(3001, function() { console.log("start server") });
为了测试,我还写了个html。data-operate.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>data-operate</title> </head> <body> <form action="./create"> <input type="submit" value="建立"> </form> <br/> <form action="./read"> <input type="submit" value="读取"> </form> <br/> <form action="./update"> <input type="submit" value="更新"> </form> <br/> <form action="./delete"> <input type="submit" value="删除"> </form> <br/> <form action="./readOne"> <input type="text" name="student_name"> <input type="text" name="student_id"> <input type="submit" value="单值读取"> </form> </body> </html>
上文是在Node中基于Mongoose对MongoDB进行增删查改(CRUD)操做的简单介绍,之后会有进阶的文章。
参考文献:
Node.js 手册查询-3-Mongoose 方法
Mongoose Schemas v4.5.8
mongoose入门