朋也的博客 » 首页 » 文章
作者:朋也
日期:2016-04-28
类别:nodejs学习笔记
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
npm i --save mongoose bluebird
//mongoose不知道从什么版本开始,在启动的时候,会提示使用bluebird
在app.js里加入下面代码
var mongoose = require("mongoose");
mongoose.Promise = require('bluebird');
mongoose.connect("mongodb://localhost/blog");
//如果数据库有用户名,密码,端口,使用下面方式连接
//mongoose.connect('mongodb://user:pass@localhost:port/database');
//对mongodb设置数据库认证的博客可以参照:https://atjiu.github.io/2017/04/25/nodejs-mongodb-auth/
本教程拿博客的数据模型做例子说明
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var BlogSchema = new Schema({
user: {type: Schema.Types.ObjectId, ref: 'User'},
title: String,
content: String,
createAt: {
type: Date,
default: Date.now
},
updateAt: {
type: Date
},
view: {
type: Number,
default: 0
},
replyCount: {
type: Number,
default: 0
}
});
// BlogSchema的静态方法,用于封装复用性比较高的一些方法
// 下面是一个分页的方法,具体参数,链式方法怎么使用参见:http://mongoosejs.com/docs/guide.html
BlogSchema.statics = {
page: function(no, size, opt, cb) {
this.find(opt)
.skip((no - 1) * size)
.limit(size)
.sort({
createAt: -1
})
.exec(cb);
}
}
module.exports = mongoose.model("Blog", BlogSchema);
在routes里新建一个路由文件,blog.js
var Blog = require("./../models/blog.js");
var Reply = require("./../models/reply.js");
var async = require("async"); //可以让nodejs的执行按照自己定义的顺序来运行的一个工具,参见:https://www.npmjs.com/package/async
// 博客详情
exports.detail = function(req, res) {
var id = req.params.id;
async.series({
blog: function(next) {
Blog.findOne({
_id: id
}, function(err, blog) {
next(null, blog);
})
},
replies: function(next) {
Reply.find({
blog: id
})
.populate("blog", "title")
.exec(function(err, replies) {
if (err) console.log(err);
console.log(replies);
next(null, replies);
})
}
}, function(err, result) {
res.render("detail", {
blog: result.blog,
replies: result.replies
})
})
}
//创建博客
exports.create = function(req, res) {
res.render("create");
};
//保存博客
exports.save = function(req, res) {
var blog = new Blog();
blog.title = req.body.title;
blog.content = req.body.content;
blog.createAt = Date.now();
blog.save(function(err, result) {
if (err) console.log(err);
res.redirect("/");
})
}
//编辑博客
exports.edit = function(req, res) {
var id = req.params.id;
Blog.findOne({
_id: id
}, function(err, blog) {
if (err) console.log(err);
res.render("edit", {
blog: blog
})
})
}
//更新博客
exports.update = function(req, res) {
var id = req.body.id;
var title = req.body.title;
var content = req.body.content;
Blog.update({
_id: id
}, {
$set: {
title: title,
content: content,
updateAt: Date.now()
}
}, function(err, result) {
if (err) console.log(err);
res.redirect("/");
})
}
//删除博客(删除方法是remove,不是delete,在sequelizejs里是destory,这个。。。只能自己去查文档了!)
exports.delete = function(req, res) {
Blog.remove({
_id: req.params.id
}, function(err, result) {
if (err) console.log(err);
res.redirect("/");
})
}
mongoose 里查询链式有个方法 populate()
官方文档里的语法是这样的
populate(path, [select], [model], [match], [options])
看着那么多参数,其实前两个就能满足大部分的关联查询的需求了,参数解释:
第一个参数可以理解为要关联查询的文档是谁 第二个参数意思是要查询关联文档里的哪些字段 如果想在关联里加入条件,可以这样写
.populate({path: 'user', match: {name: req.query.name}})
下面以博客评论的model来说明
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var ReplySchema = new Schema({
blog: {//这个字段就是blog与reply的关联字段,保存的是blog的id,如果查询某一条回复是属于哪个博客的,就需要这个字段来建立联系
type: ObjectId,
ref: "Blog"//表示当前字段指向哪个文档(也就是关联的哪个表)
},
content: String,
createAt: {
type: Date,
default: Date.now
},
up: {
type: Number,
default: 0
},
down: {
type: Number,
default: 0
}
})
module.exports = mongoose.model("Reply", ReplySchema);
关于查询,可以参见博客的crud代码里的detail方法,下面只贴出关联查询部分代码,上面代码贴的有全部的
exports.detail = function(req, res) {
var id = req.params.id;
async.series({
blog: function(next) {
Blog.findOne({
_id: id
}, function(err, blog) {
next(null, blog);
})
},
replies: function(next) {
Reply.find({
blog: id
})
.populate("blog", "title") //将reply与blog关联,并只查出blog的标题,查询出来的数据结构是:{_id: xxx, blog: {title: xxx, _id: xxx}, createAt: xxx ...} 详见console.log(replies), 如果想关联查出blog里的多个字段,populate 第二个参数以空格分割,如:.populate('blog', 'title content')
.exec(function(err, replies) {
if (err) console.log(err);
console.log(replies);
next(null, replies);
})
}
}, function(err, result) {
res.render("detail", {
blog: result.blog,
replies: result.replies
})
})
}