跳到主要内容

Sequelize 在博客内容列表中的落地

· 阅读需 3 分钟
一介布衣
全栈开发者 / 技术写作者

如果说模型、关联、分页都是准备动作,那么真正让人感受到 ORM 价值的,还是内容列表。博客首页、分类页、归档页、后台管理页,本质上都在围绕“把文章列表稳定地拉出来”这件事打转。

我在用 Sequelize 做博客内容列表时,最看重三件事:

  • 一套统一的筛选参数
  • 稳定的排序规则
  • 明确控制哪些关联在列表阶段就加载

一个适合博客列表的查询函数

const { Op } = require('sequelize');

async function queryContentList(params) {
const page = Math.max(Number(params.page) || 1, 1);
const pageSize = Math.min(Number(params.pageSize) || 12, 30);

const where = {
status: 'published',
};

if (params.categorySlug) {
where['$category.slug$'] = params.categorySlug;
}

if (params.keyword) {
where[Op.or] = [
{ title: { [Op.like]: `%${params.keyword}%` } },
{ summary: { [Op.like]: `%${params.keyword}%` } },
];
}

return Post.findAndCountAll({
where,
include: [
{
model: Category,
as: 'category',
attributes: ['name', 'slug'],
},
],
attributes: ['id', 'title', 'slug', 'summary', 'publishedAt'],
order: [
['publishedAt', 'DESC'],
['id', 'DESC'],
],
limit: pageSize,
offset: (page - 1) * pageSize,
});
}

这个思路最适合拿来支撑下面几类页面:

  • 首页最新文章
  • 某个分类下的文章列表
  • 后台内容管理列表
  • 归档页的时间倒序列表

为什么我会加第二排序字段

只按 publishedAt DESC 排序在大多数时候没问题,但如果多篇文章发布时间一样,分页切换时顺序可能不稳定。所以我通常会补一个 id DESC 作为兜底。

列表阶段尽量只查轻量字段

技术博客正文很长,列表页通常不需要完整 content。如果每次都把大字段带出来,数据库、网络和接口序列化都会变重。

比较稳的做法是:

  • 列表页只返回 titlesummaryslugpublishedAt
  • 详情页再单独查正文

ORM 真正帮了什么忙

到这一步你会发现,Sequelize 真正有用的地方,不是它把 SQL 藏起来了,而是它让“内容列表是一套可以复用的查询逻辑”这件事变得更清楚:

  • 首页和后台共用一套基础查询条件
  • 分类页只是多了一层筛选
  • 归档页只是换了一种聚合和展示方式

这就是 ORM 在博客系统里的价值。它不是魔法,而是让我们更容易把内容读取逻辑收成一个稳定边界。

小结

内容列表一旦稳住,博客系统的大部分用户感知问题就已经解决一半了。Sequelize 在这里最适合扮演的角色,就是把这些散落在各个接口里的查询规则收拢成一套长期可维护的方案。