在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)

关键词:mongodb装置 mongoose运用 robomongo mongoose的CRUD操纵 mongoose的查询,增添,修正,删除

东西引见

MongoDB

MongoDB是基于Javascript言语的数据库,存储花样是JSON,而Node也是基于JavaScript的环境(库),所以node和mongoDB的搭配能削减由于数据转换带来的时刻空间开支。

Mongoose

是MongoDB的一个对象模子东西,它将数据库中的数据转换为JavaScript对象以供你在运用中运用,封装了MongoDB对文档的的一些增编削查等经常使用要领,让NodeJS操纵Mongodb数据库变得越发天真简朴。

Robomongo

一个可视化的mongoDB操纵软件,类似于mysql的navicat可视化东西。

捋一捋它们的关联,mongoDB是一个数据库,mongoose是你在本身代码中操纵mongo数据库的接口,而robomongo是mongo数据库的可视化东西,经由过程它的界面轻易直接操纵数据库内容。

东西装置

MongoDB装置

1.装置mongoDB

到官网https://www.mongodb.com/download-center#community下载顺序装置,挑选custom情势就行。

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装置文件。装置重启即可。

Robomongo装置以及运用

直接到官网https://robomongo.org/下载装置,装置胜利后运转,第一次运转,须要新建立一个衔接,如图建立test,点击save保留衔接。

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

挑选test,点击connect衔接数据库。robomongo会本身搜刮你体系内里装置的mongodb并与其衔接。如图

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

衔接胜利后,显现你的数据库,在这个节目能够对数据库举行操纵。如图:

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

Mongoose装置与加载

起首假定你已装置了 Node.js,敕令行东西输入:

$ npm install mongoose -g

在运用的文件中require(“mongoose”);即可。

运用Mongoose举行CRUD操纵

运用基础步骤

Mongose基于mongodb的原生要领,本身定义了一套操纵MongoDB数据库的接口,比原生要领越发简朴轻易。为了越发直观,下面的步骤连系例子来讲。如果我须要做一个教务体系,须要存储门生Student的信息,门生信息平常包含姓名name,学号id,电话phone,登录日期date等。我把门生的信息存在mongodb的myDB数据库中,鸠合的名字叫students。如图:

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

_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会涌现以下毛病(这个毛病没有什么影响):

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

意义是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,如图:

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

经由过程{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)操纵。

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检察数据库,能够看到数据已寄存胜利,如图

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

2.CRUD之read

运用MyStudent模子挪用find()要领返回students鸠合的一切内容,第一个参数定义前提,第二个参数是回调函数,回调函数中的docs是返回的是查找效果,效果情势为一个json数据数组[{},{}]。

    var MyStudent = mongoose.model("Student");
    MyStudent.find({}, function(err, docs) {});

比方数据库students鸠合中,有以下数据:

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

运转上面代码,效果console.log输出显现以下:

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

模子还能够挪用其他许多查询的函数,比方

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){});

运转如上代码前,如图

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

运转如上代码后,如图

《在Node中基于Mongoose对MongoDB举行增删查改(CRUD)操纵(一)》

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入门

CSDN个人博客地址–点击这里

    原文作者:sam976
    原文地址: https://segmentfault.com/a/1190000006123880
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞