搜尋
首頁web前端js教程Nodejs使用Mongoose創建模型及API

這次帶給大家Nodejs使用Mongoose創建模型及API ,Nodejs使用Mongoose創建模型及API的注意事項有哪些,以下是實戰案例,一起來看一下。

MongoDB是一種分散式文件儲存型資料庫,和平時使用的關係型資料庫不同,它儲存的是BSON格式(json的二進位),特點是高效能、易部署,易使用...(詳情請見百科),主要一點它支援JavaScript讀寫,MEAN堆疊開發的最大特點就是前後端包含資料庫都是JavaScript編寫。而Mongoose可以類比EntityFramwork(ORM-物件關係映射),主要做用是讓開發人員可以更方便的操作資料庫。開始之前,記得先安裝mongodb。

一、MongoDB準備工作

1. mongo安裝完之後,用cmd切到安裝目錄下面的bin目錄。執行mongo,如果出現版本號則說明啟動成功:

 

如果是出現“電腦積極拒絕”,需要設定下dbpath,也就是指定資料的路徑。

mongod --dbpath=c:\mongodb\db

成功之後,可以造訪http://localhost:28017/ ,可以看到以下頁面:

說明一切就緒。

2.為避免每次開機完都要設定dbpath,需要將mongo設定為服務啟動。分兩步,先用管理員身分開啟cmd,切到mongo的bin目錄:

D:\mongodb\bin>mongod --dbpath=D:\mongodb --logpath=D:\mongodb\log.txt --install

以上路徑更換成自己的路徑,然後在運行框中輸入services.msc。設定服務的時候要確保mongo在運作狀態,不然設定不會成功。

開啟文件,找到Mongo DB:

右鍵選擇啟動,這樣每次開機mongo就會自動運行。

3.比較方便點,可以在桌面上建立一個star.bat檔:

@echo off
start "" "D:\mongodb-win32-i386-2.0.6\bin\mongo.exe"

 這樣每次點選直接進入指令框:

 

4.常用指令/基本操作 

查看db:

show dbs

切換到某個資料庫:

switched to db dbname
或者:
use dbname

查看某個資料庫下的集合

show collections

查看集合下面的文件:

db.collections.find()

 

因為這一節的重點不是要介紹如何在cmd中操作mongo,所以不再贅述了。更多這樣的細節可以參考一線碼農的部落格:8天學通mongoDB。如果是沒有安裝sp1的電腦,官網的3.0版本安裝成功後無法運作,可以用2.xx免安裝版。接下來主要講Mongoose的操作。

二、Mongoose

1.安裝

你可以用npm直接安裝:

也可以用vs進行安裝。右鍵工程上的npm,選擇Install New npm Packages。

第一次會下載安裝一個工具,安裝完成之後,搜尋Mongoose,出現下面的介面,並安裝。

2.建立連線

到這一步環境終於是準備好了,接下來在app_server 資料夾下建立一個models目錄,並新建一個db.js

並在db.js中引用Mongoose:

var mongoose = require('mongoose');

mongodb不需要在连接它之前创建数据库,当第一次连接的时候,会根据链接自动创建。Mongoose在连接MongoDB的时候会创建一个有五个可重用的连接的连接池,连接数是可以配置的。这么做的原因是因为连接数据库是比较耗时的操作,特别是分布式的数据库。连接字符串的规则如下:

这里用户名、密码、端口都是可以省略的,那么在本地的时候我们的连接字符串就如下:

var dbURI = 'mongodb://localhost/RClub';
mongoose.connect(dbURI);

命名我们的数据库为RClub。Mongoose会基于连接的状态发布不同的事件:

mongoose.connection.on('connected', function () {
    console.log('Mongoose connected to ' + dbURI);
});
mongoose.connection.on('error', function (err) {
    console.log('Mongoose connection error: ' + err);
});
mongoose.connection.on('disconnected', function () {
    console.log('Mongoose disconnected');
});

如此我们可以监听连接的状态。另外应用终止需要监听nodejs的进程的SIGINT事件。而如果是nodemon重启,需要监听的是SIGUSR2事件,以便关闭连接。

// 当应用重启或终止的时候 关闭连接Shutdown = function (msg, callback) {
    mongoose.connection.close(function () {
        console.log('Mongoose disconnected through ' + msg);
        callback();
    });
};// nodemon 重启 process.once('SIGUSR2', function () {
    Shutdown('nodemon restart', function () {
        process.kill(process.pid, 'SIGUSR2');
    });
});// 应用终止process.on('SIGINT', function () {
    Shutdown('app termination', function () {
        process.exit(0);
    });
});

View Code

运行nodemon:

显示连接成功!

3.数据模型

Mongoose封装了mongodb的api使之更便于调用,但作为MongoDB的对象-文档建模器,有着更强大的功能。在mongodb中,每一个条目就是一个document,相当于关系型数据库中的行,而document的集合称为collection,相当于是关系型数据库中的table。在Mongoose中定义一个document的对象称为schema,相当于用EF定义一个Model,而定义schema中每一条数据的规则称为path(约束)。path的规则和jquery.validate.js几乎是一样的。

path支持的数据类型如下:

  • String

  • Number

  • Date

  • Boolean

  • Buffer   二进制,比如图形

  • Mixed  任何类型

  • Array  可以为数组,或者内嵌的 子文档集

  • ObjectId 唯一id

接下来演示下如何用Mongoose建一个数据模型,在models文件夹下创建一个books.js。然后引用Mongoose。如下,更具上一节book对象创建一个bookSchema 。

  {
    id: 0"深入浅出Node.js""朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00"5"https://img3.doubanio.com/mpic/s27269296.jpg""node", "深入浅出"'本书从不同的视角介绍了 Node 内在的特点和结构。.....9787115335500

id不用创建,mongo会为每个document生成一个唯一的id。

var mongoose = require('mongoose');var bookSchema = new mongoose.Schema({
    title: String,
    rating: {
        type: Number,
        required: true,
        min: 0,
        max: 5
    },
    info: String,
    img: String,
    tags: [String],
    brief: String,
    ISBN: String
});

这种语法是不是和jquery.validate.js很像,相信不用解释就能看明白,不满足path的条件时是不能保存或者更改的。每个path还可以设置默认值,比如时间:

 createdOn: {
        type: Date,        default: Date.now
    },

一个Schema可以包含另外的Schema或数组,在关系型数据库中这种需求用的是外键或者是关系映射表,而Mongoose这样看起来直观多了。

var userSchema = new mongoose.Schema({
userName: String,
    email: String,
...});var commentSchema = new mongoose.Schema({
    user: userSchema,
    ...
    content: String
});var topicSchema = new mongoose.Schema({
    ....
    visitedCount: { type: Number, default: 0 },
    ...
    comments: [commentSchema],
    deleted: { type: Boolean, default: false },
    top: { type: Boolean, default: false }, // 置顶帖    ...
});

这个时候的shema 还不具备数据库的操作能力,还需要注册下。 

mongoose.model('Book', bookSchema);
mongoose.model('Topic', topicSchema);

全部模型:

var mongoose = require('mongoose');var bookSchema = new mongoose.Schema({
    title: String,
    rating: {
        type: Number,
        required: true,
        min: 0,
        max: 5
    },
    info: String,
    img: String,
    tags: [String],
    brief: String,
    ISBN: String
});var userSchema = new mongoose.Schema({
    userName: String,
    email: String,
    password: String,
    createdOn: {
        type: Date,        default: Date.now
    },
    img: String,
    ip: String,
    mobile: String
});var commentSchema = new mongoose.Schema({
    user: userSchema,
    createdOn: {
        type: Date,        default: Date.now
    },
    content: String
});var topicSchema = new mongoose.Schema({
    title: String,
    type: String,
    visitedCount: { type: Number, default: 0 },
    commentCount: { type: Number, default: 0 },
    createdOn: {
        type: Date,        default: Date.now
    },
    img: String,
    author: String,
    content: String,
    comments: [commentSchema],
    deleted: { type: Boolean, default: false },
    top: { type: Boolean, default: false }, // 置顶帖
    good: { type: Boolean, default: false }, // 精华帖});
mongoose.model('Book', bookSchema);
mongoose.model('Topic', topicSchema);

View Code

4.操作数据

接下来就是改造controllers文件夹的中的home.js了,首先要引用db.js和Mongoose。

var db = require('../models/db.js');var mongoose = require('mongoose');

 1).初始化数据,查询与新建数据。

 这里把上一节创建的数据books和topics存入数据库中:

module.exports.init = function (req, res) {    mongoose.model('Book').find().exec(function (err, objs) {        if (err) {
            res.render('error', {
                message: err.message,
                error: err
            });            return;
        }        if (objs.length) {            
            for (var i = 0; i <p style="text-align: left;">这段代码里面有查询和新建保存,mongoose.model("Book") 相当于EF中的db.Books。而这里的find()方法并没有立即执行,这里有点像Linq的感觉,可以链式查询:</p><pre class="brush:php;toolbar:false">Book.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec(callback);//例子,和上面的book没有关系

这里Book相当于mongoose.model("Book") ,而{ size: 'small' }是一个条件。最终到exec方法时才正在执行。回调函数默认有两个参数,一个是err,一个是结果对象。这里偷了懒只判断了books的查询结果,集合为空的话就加上原来的数据。因为mongoose.model("Book")使用的比较多,所以干脆提出来:

var Bookmodel = mongoose.model('Book');var Topicmodel = mongoose.model('Topic');

find方法是查询一个集合,常用的还有findone:

var query = Person.findOne({ 'name.last': 'Ghost' });// 选择name和occupation 字段query.select('name occupation');// 执行查询query.exec(function (err, person) {  if (err) return handleError(err);
  console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation) 
})

保存数据,new一个Model,传入初始化的对象,save即可。

 var taget = new Bookmodel(books[i]);
      taget.save(function (err) {
               console.log(err);
          });

配置下路由:

router.get('/init', homeController.init);

运行:

因此数据添加成功!

三、app_api

为方便后面复用,接下来将数据调用换成api的方式。在工程里面新建一个app_api文件夹,并将原来app_server目录下的models文件移过去。并增加controllers和routes文件夹。也就是说,把数据调用分离出来。

1)在app.js中增加以下代码:

var routesApi = require('./app_api/routes/index');...
app.use('/', routes);app.use('/api', routesApi);

也就是说,所有以/api/xx开始的请求将由routes/index.js来路由。

2)在routes文件下新增index.js 文件,用来配置api的路由:

var express = require('express');var router = express.Router();var bookCtrl = require('../controllers/book');var topicCtrl = require('../controllers/topic');
router.get('/books', bookCtrl.books);
router.post('/book', bookCtrl.bookCreate);
router.get('/book/:bookid', bookCtrl.bookReadOne);
router.put('/books/:bookid', bookCtrl.bookUpdateOne);
router.delete('/books/:bookid', bookCtrl.bookDeleteOne);//topicsrouter.get('/topics', topicCtrl.topics);
module.exports = router;

路由覆盖了增删改查,暂时先实现这部分的路由。后面根据需求再增加。

3)controller实现

一个成功的Restful API应该包含返回的数据和http的状态码,因此我们定义了一个公用方法:

var sendJSONresponse = function (res, status, content) {
    res.status(status);
    res.json(content);
};

比如定义一个bookReadOne方法:

module.exports.bookReadOne = function (req, res) {    var bookid = req.params.bookid;    if (!bookid) {
        sendJSONresponse(res, 404, {            "message": "Not found, bookid is required"
        });        return;
    }
    BookModel.findById(bookid).exec(function (err, book) {        if (!book) {
            sendJSONresponse(res, 404, {                "message": "bookid not found"
            });            return;
        } else if (err) {            sendJSONresponse(res, 400, err);            return;
        }
        console.log(book);        sendJSONresponse(res, 200, book);
    });
}

请求成功发送状态码200和结果,请求失败则发送404或者500及错误。

books.js:

var mongoose = require('mongoose');var BookModel = mongoose.model('Book');var sendJSONresponse = function (res, status, content) {
    res.status(status);
    res.json(content);
};
 
module.exports.books = function (req, res) {
    BookModel.find().exec(function (err, books) {        if (err) {
            console.log(err);
            sendJSONresponse(res, 400, err);            return;
        }
        sendJSONresponse(res, 200, books);
    });
}
module.exports.bookCreate = function (req, res) {
    BookModel.create({
        title: req.body.title,
        info: req.body.info,
        img: req.body.img,
        tags: req.body.tags,
        brief: req.body.brief,
        ISBN: req.body.ISBN
    }, function(err, book) {        if (err) {
            console.log(err);
            sendJSONresponse(res, 400, err);
        } else {
            console.log(book);
            sendJSONresponse(res, 201, book);
        }
    });
}
module.exports.bookReadOne = function (req, res) {    var bookid = req.params.bookid;    if (!bookid) {
        sendJSONresponse(res, 404, {            "message": "Not found, bookid is required"
        });        return;
    }
    BookModel.findById(bookid).exec(function (err, book) {        if (!book) {
            sendJSONresponse(res, 404, {                "message": "bookid not found"
            });            return;
        } else if (err) {
            sendJSONresponse(res, 400, err);            return;
        }
        console.log(book);
        sendJSONresponse(res, 200, book);
    });
}
module.exports.bookUpdateOne = function (req, res) {    var bookid = req.params.bookid;    if (!bookid) {
        sendJSONresponse(res, 404, {            "message": "Not found, bookid is required"
        });        return;
    }
    BookModel.findById(bookid).exec(function (err, book) {        if (!book) {
            sendJSONresponse(res, 404, {                "message": "bookid not found"
            });            return;
        } else if (err) {
            sendJSONresponse(res, 400, err);            return;
        }
        book.title = req.body.title;
        book.rating = req.body.rating;
        book.info = req.body.info;
        book.img = req.body.img;
        book.tags = req.body.tags;
        book.brief = req.body.brief;
        book.ISBN = req.body.ISBN;
        book.save(function (err, book) {            if (err) {
                sendJSONresponse(res, 404, err);
            } else {
                sendJSONresponse(res, 200, book);
            }
        });
    });
}
module.exports.bookDeleteOne = function (req, res) {    var bookid = req.params.bookid;    if (bookid) {
        BookModel.findByIdAndRemove(bookid)
            .exec(function (err) {            if (err) {
                console.log(err);
                sendJSONresponse(res, 404, err);                return;
            }
            console.log("book id :" + bookid + "deleted");
            sendJSONresponse(res, 204, null);
        });
    } else {
        sendJSONresponse(res, 404, { message: "No bookid" });
    }
}

View Code

这样注意一点是,find()、findbyid和findByIdAndRemove不是立即执行,是在exec方法中执行,但是create,save是立即执行的。

5)、调用api

接下来就是在app_server下的controller中调用上面定义的api。在这里需要安装一个request模块,request让http请求变的更加简单。

 在home.js中引用request:

var request = require('request');

request的调用如下:

request(options, callback)

包含options和回调两部分,options结构如下,包含url,method,json和qs四部分。

var requestOptions = {
url : "http://yourapi.com/api/path",
method : "GET",
json : {}, //请求体的JavaScript对象qs : {
offset : 20 //查询字符串}
};

而默认的回调格式如下:

function(err, response, body) {if (err) {
console.log(err);
} else if (response.statusCode === 200) {
console.log(body);
} else {
console.log(response.statusCode);
}
}

修改index方法,先定义一个apiOptions,只想默认路径,记得在发布的时候修改为带域名的地址。

var apiOptions = {
    server : "http://localhost:3000"};
module.exports.index = function (req, res) {    var requestOptions, path;
    path = "/api/topics";
    requestOptions= {
        url: apiOptions.server + path,
        method: "GET",
        json:{},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('index', { title: 'Index', topics: body });
        } else {
            res.render('error', { message: err.message, error: err });
        }
    });
};

这样就进行了分离,home.js不在需要引用Mongoose部分。

home.js:

var request = require('request');var apiOptions = {
    server : "http://localhost:3000"};//if (process.env.NODE_ENV === 'production') {//    apiOptions.server = "https://stoneniqiu-mean.herokuapp.com/ ";//}module.exports.index = function (req, res) {    var requestOptions, path;
    path = "/api/topics";
    requestOptions= {
        url: apiOptions.server + path,
        method: "GET",
        json:{},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('index', { title: 'Index', topics: body });
        } else {
            res.render('error', { message: err.message, error: err });
        }
    });
};
module.exports.books = function (req, res) {    var requestOptions, path;
    path = "/api/books";
    requestOptions = {
        url: apiOptions.server + path,
        method: "GET",
        json: {},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('books', { title: 'Books', books: body });
        } else {
            res.render('error', { message: err.message, error: err });
        }
    });
};
module.exports.detail = function (req, res) {    var requestOptions, path;
    path = "/api/book/" + req.params.id;
    requestOptions = {
        url: apiOptions.server+path ,
        method: "GET",
        json: {},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('detail', { title: body.title, book: body });
        } else {
            res.render('info', err);
        }
    });
   
   };
module.exports.about = function (req, res) {
    res.render('about', { title: 'About' });
};

View Code   

更多查询可以移步:http://mongoosejs.com/docs/queries.html

在首页,需要处理一下时间显示的问题,增加了一个mixin

mixin formatDate(dateString)  -var date = new Date(dateString);  -var d = date.getDate();  -var monthNames = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ];  -var m = monthNames[date.getMonth()];  -var y = date.getFullYear();  -var output = y + '/' + m + '/' + d;  =output

调用:

   span.pull-right           +formatDate(topic.createdOn)

页面如下:

初步改造完成。之前还写了一个基于回调的service方式的controller和service,类似于C#中的分离。后来觉得还是api的方式更好,留在这里可以当一个参考。

home.js:

var bookservice = require('../services/homeService.js');
 
module.exports.index = function (req, res) {
    bookservice.allTopics(function (result) {
        var obj = result.content;
        console.log(obj.status);        if (result.status == 200) {
            res.render('index', { title: 'Index', topics: obj });
        }
        res.render('info', obj);
    });  
};
module.exports.books = function (req, res) {
    bookservice.allBooks(function(result) {
        var obj = result.content;
        console.log(obj.status);        if (result.status == 200) {
            res.render('books', { title: 'Books', books: obj });
        }
        res.render('info', obj);
    });  
};
module.exports.detail = function (req, res) {
    bookservice.bookReadOne(req.params.id, function (result) {
        var obj = result.content;        if (result.status == 200) {
            res.render('detail', { title: obj.title, book: obj });
        } 
        res.render('info', obj);
    });
   };
module.exports.about = function (req, res) {
    res.render('about', { title: 'About' });
};

View Code

homeService.js:

var mongoose = require('mongoose');var db = require('../models/db.js');var Bookmodel = mongoose.model('Book');var Topicmodel = mongoose.model('Topic');var jsonResult = function (status, content) {    return { status: status, content: content };
};
module.exports.bookReadOne = function (id,callback) {
    console.log('Finding book details', id);    if (!id) {
        console.log('No bookid specified');        return jsonResult(404, { "message": "No bookid specified" });
    }
    Bookmodel.findById(id).exec(function (err, book) {        if (err) {
            callback(jsonResult(404, err));            return;
        }        if (!book) {
            callback(jsonResult(404, { "message": "book not found" }));            return;
        }
       callback(jsonResult(200, book));
    });
};
module.exports.allBooks=function(callback) {
    Bookmodel.find().exec(function (err, books) {        if (err) {
            callback(jsonResult(404, err));            return;
        }        if (!books.length) {
            callback(jsonResult(404, { "message": "books not found" }));            return;
        }
        callback(jsonResult(200, books));
    });
}
module.exports.createBook = function (book, callback) {    var t = new Bookmodel(book);
    t.save(function (err) {
        callback(err);
    });
}
module.exports.allTopics=function(callback) {
    Topicmodel.find().exec(function (err, topics) {        if (err) {
            callback(jsonResult(404, err));            return;
        }        if (!topics.length) {
            callback(jsonResult(404, { "message": "topics not found" }));            return;
        }
        callback(jsonResult(200, topics));
    });
}
module.exports.createTopic=function(topic, callback) {    var t = new Topicmodel(topic);
    t.save(function(err) {
        callback(err);
    });
}var books = [
    {
        id: 0,
        title: "深入浅出Node.js",
        info: "朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00",
        rating: 5,
        img: "https://img3.doubanio.com/mpic/s27269296.jpg",
        tags: ["node", "深入浅出"],
        brief: '本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码规范和NPM 仓库等事宜。本书适合想深入了解 Node 的人员阅读。'
        ,ISBN: 9787115335500
    },
    {
        id: 1,
        title: "程序员修炼之道 : 从小工到专家",
        info: "Andrew Hunt、David Thomas / 马维达 / 电子工业出版社 / 2005-1 / 48.00元",
        rating: 5,
        img: "https://img3.doubanio.com/mpic/s3957863.jpg",
        tags: ["程序人生", "软件开发"],
        brief: '《程序员修炼之道》由一系列的独立的部分组成,涵盖的主题从个人责任、职业发展,直到用于使代码保持灵活、并且易于改编和复用的各种架构技术。利用许多富有娱乐性的奇闻轶事、有思想性的例子以及有趣的类比,全面阐释了软件开发的许多不同方面的最佳实践和重大陷阱。无论你是初学者,是有经验的程序员,还是软件项目经理,本书都适合你阅读。'
        ,ISBN: 9787505397194
    },
    {
        id: 2,
        title: "Getting MEAN with Mongo, Express, Angular, and Node",
        info: "Simon Holmes / Manning Publications / 2015-11-26 / USD 44.99",
        rating: 4,
        img: "https://img3.doubanio.com/mpic/s27676844.jpg",
        tags: ["node", "web开发", "编程"],
        brief: 'MEAN栈开发,比较详尽的的应用开发书籍'
        , ISBN: 9781617292033
    }
];var topics = [
    {
        title: "书山有路第十一期:程序员修炼之道-第二章-注重实效的途径--第五天",
        type: "读书",
        visitedCount: 80,
        commentCount: 2,
        createdOn: '2016/5/15 21:32',
        author: 'stoneniqiu',
        img: 'http://upload.jianshu.io/users/upload_avatars/133630/d5370e672fd4.png?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "《明朝那些事儿》之闲言散语",
        type: "书评",
        visitedCount: 180,
        commentCount: 20,
        createdOn: '2016/5/15 21:32',
        author: '卡卡卡萨布兰卡 ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1675188/2d0810ccc03d.jpg?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "有《程序员修炼之道》高清版吗?",
        type: "求书",
        visitedCount: 90,
        commentCount: 1,
        createdOn: '2016/5/15 21:32',
        author: '吾不知 ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1125491/3910f3825f73.jpg?imageMogr/thumbnail/90x90/quality/100',
    },
    {
        title: "《国富论》-读书笔记",
        type: "书评",
        visitedCount: 180,
        commentCount: 20,
        createdOn: '2016/5/15 21:32',
        author: '寻海 '
        ,img: 'http://upload.jianshu.io/users/upload_avatars/133630/d5370e672fd4.png?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "《高效人士的七个习惯》读书笔记",
        type: "书评",
        visitedCount: 180,
        commentCount: 20,
        createdOn: '2016/5/15 21:32',
        author: '书虫纪庆 ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1429280/454c495361f9.jpg?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "《css揭秘》这本书如何",
        type: "求索",
        visitedCount: 58,
        commentCount: 3,
        createdOn: '2016/5/15 21:32',
        author: 'Watery_D_Lotus ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1449533/a2d98762484a.jpg?imageMogr/thumbnail/90x90/quality/100'
    }
];//module.exports.bookCreate = function (req, res) {//    var book = {//        title: "test",//        info: "Simon Holmes / Manning Publications / 2015-11-26 / USD 44.99",//        rating: 4,//        img: "https://img3.doubanio.com/mpic/s27676844.jpg",//        tags: ["node", "web开发", "编程"],//        brief: 'MEAN栈开发,比较详尽的的应用开发书籍',//        ISBN: 9781617292033//    };//    var b = new Bookmodel(book);//    b.save(function (err) {//        if (err) {//            console.log(err);//            res.render('error', {//                message: err.message,//                error: err//            });//        }//        res.render('info', { message: "添加成功!", success: true });//    });//};//module.exports.bookDelete = function (req, res) {//    Bookmodel.findOneAndRemove({ title: "test" }, function (err) {//        if (err) {//            console.log(err);//            res.render('error', {//                message: err.message,//                error: err//            });//        }//        res.render('info', { message: "删除成功!", success: true });//    });//};

View Code

至此,这三个页面的数据全部都是通过api从数据库中获取。那么现在我们要发布,本地数据库显然是不行。那怎么办呢?

四、mlab,500M MongoDB免费空间!

 mlab是一个提供部署在云端的mongodb数据库服务平台,可以对每个用户免费提供500M空间。

 1. 先注册一个账号:https://mlab.com/,并验证邮箱:

 2.点击Create new创建数据库:这里选择亚马逊的单用户sanbox会有免费的500M空间。

 输入数据库名称,并创建

3.创建成功之后,给数据库创建一个用户

 4.连接字符串: 

 第一个字符串是用cmd连接,第二个用于我们的程序。修改db.js 连接成功:

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样用nodejs搭建服务器

vue2全家桶是什么,如何使用?

以上是Nodejs使用Mongoose創建模型及API的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript數據類型:瀏覽器和nodejs之間是否有區別?JavaScript數據類型:瀏覽器和nodejs之間是否有區別?May 14, 2025 am 12:15 AM

JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

JavaScript評論:使用//和 / * * / * / * /JavaScript評論:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境