12.3 沸点管理接口
沸点是一个交友论坛,跟朋友圈差不多,用于分享简短的图文消息。从数据上看它是一个小型的文章集合。我们参考文章集合的设计,设定沸点集合的字段如下:
- content:沸点内容,必填。
- images:沸点图片,数组。
- created_by:沸点创建者,必填。
- created_at:沸点创建时间。
- group:所属圈子标识。
一共五个字段,已经可以覆盖业务需求了,点赞和评论的数据放在单独的集合中。我们需要创建一组圈子数据,与文章分类一样,是一组静态数据。在 config/static.js 中添加 groups 变量并导出:
const groups = [
{
key: "daily",
label: "打工日常",
},
{
key: "techno",
label: "技术圈",
},
{
key: "blind_date",
label: "相亲角",
},
{
key: "slack_off",
label: "上班摸鱼",
},
{
key: "eating",
label: "早中晚吃啥",
},
{
key: "playing",
label: "下班去哪玩",
},
{
key: "bigtea",
label: "好大一个瓜",
},
];
module.exports = { groups };
接着我们创建模型,新建 model/shortmsgs.js 文件,并导入上面的 group 变量:
const { ObjectId } = mongoose.Types;
const { groups } = require("../config/static");
const shortmsgsSchema = new mongoose.Schema({
content: { type: String, required: true },
images: { type: [String], default: [] },
created_by: { type: ObjectId, required: true },
created_at: { type: Date, default: Date.now },
group: {
type: String,
enum: groups.map((group) => group.key),
required: true,
},
});
const Model = mongoose.model("shortmsgs", shortmsgsSchema);
模型创建之后,就可以进入路由开发的环节了。
12.3.1 创建沸点接口
新建路由文件 router/shortmsgs.js,并添加一个创建沸点的路由如下:
// router/shortmsgs.js
var StmsgsModel = require('../model/shortmsgs')
router.post('/create', async (req, res, next) => {
let body = req.body
try {
let result = await StmsgsModel.create(body)
res.send(result)
} catch (err) {
...
}
})
在路由文件 config/router.js 中注册该路由:
const stmsgsRouter = require("../router/shortmsgs.js");
const router = (app) => {
...
app.use("/stmsgs", stmsgsRouter);
};
经过这一套标准流程,现在创建沸点的接口就能用了。我们测试调用该接口,返回结果如下:
12.3.2 沸点列表接口
沸点列表需要关联查询点赞和评论数据,因此要用到聚合管道,具体方法和文章列表类似。创建路径为 “/list”,方法为 GET 的沸点列表路由,代码如下:
router.get('/lists', async (req, res, next) => {
let { group, user_id, orderby } = req.query
try {
let orderby = orderby || 'new'
if(!['new', 'hot'].includes(orderby)) {
return res.status(400).send({ message: 'orderby 参数错误' })
}
let where = { }
if (group) {
where.group = group
}
let result = await StmsgsModel.aggregate([
{ $match: where },
...
])
res.send(result)
} catch (err) {
...
}
})
上面代码中接收了 group 参数表示圈子标识,支持通过圈子筛选沸点。同时根据 orderby 参数决定数据排序规则,支持按时间、按热度两种排序方式。
参数处理后进入聚合管道,第一个管道是过滤沸点,其余的管道逻辑代码如下:
[
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "source_id",
as: "comments",
},
},
{
$lookup: {
from: "praises",
localField: "_id",
foreignField: "target_id",
as: "praises",
},
},
{
$addFields: {
is_praise: {
$in: [ObjectId(user_id), "$praises.created_by"],
},
praises: {
$size: "$praises",
},
comments: {
$size: "$comments",
},
},
},
{
$sort: orderby == "new" ? { created_at: -1 } : { comments: 1, praises: 1 },
},
];
管道逻辑主要是查询集合对应的评论和点赞数量,并使用新的管道阶段 $sort 对文档排序。排序规则是根据一个或多个字段进行升降排序,其中 1 代表升序、-1 代表降序。
测试该接口,可以看到返回结果如下:
12.3.3 沸点评论与点赞接口
沸点的评论与点赞接口不需要重新开发,因为文章的评论与点赞接口已经兼容了沸点,我们可以直接使用,只需要在传参时使用正确的标识参数。
当使用评论相关接口时,参数传入 source_type=2;使用点赞相关接口时,参数传入 target_type=2,这样就能标记沸点内容,与文章的数据区分开。