一. 需求
我看现在后台管理系统访问用户列表的接口返回的越来越慢,之前因为数据少,我是没做分页的,现在眼看数据越来越多,返回也越来越慢(因为这个接口还有一些关联查询),我开始给它加入分页功能.
ui 选的是 Element 的 Pagination
组件
后端用的是 ORM
为 Sequelize
驱动的 nodejs
前端怎么做大家应该都比较清楚, 我就说说后端这边吧.
我用了 findAndCountAll
方法
这个方法会在查出列表记录的同时, 还会返回符合你查询列表数据的条数
二. 遇到的坑~
我写了个接口 getUserList
- 参数 currentPage 就是当前是第几条.
- 参数 count 是每次查询几条数据
router.get('/getUserList', async (ctx, next) => {
let {currentPage=1, count=10} = ctx.request.header;
let offset = (currentPage - 1) * count;
let userList = await models.user.findAllAndCount({
limit: parseInt(count),
offset,
include: [
{
model: {
explore
}
]
}).then(res => {
let result = {};
result.data = res.rows;
result.totalCount = res.count;
return result;
});
ctx.body = userList;
});
findAllAndCount
和 findAll 方法返回的不一样,它的返回是
- res.rows, 列表数据
- count, 返回的总条数 (不受 limit 和 offset 影响,分页的关键数据)
可是查出来却发现数据其实数据不大对.
实际上应该只有 200 条,查出来的却有 250 条.
我直接写 sql 查询select count(*) user
也是 200 条.
所以 250 这个数据显然不对
好了,去问问谷歌爸爸吧~
sequelize 的 github 2016年就有人提了这个issue
result.count for findAndCountAll is incorrect with include
看来不止我 一个人碰到这种情况~
三. 解决问题
但是好奇怪啊,但是这里为我点明了一个出现 bug 的规律.
那就是条数错误的情况大家都发生在查询里含有 include 的时候,
国内的一位开发就直接的说出了什么情况下返回的 count 会是错误的
如下,Sequelize查询的数据表只有14条数据,但查询结果是36,只要不加include条件就是正确的14,是带上了include中的Comments表的数据,求解
终于真相大白了.
有开发说了解决办法
distinct:true //这一句可以去重,它返回的 count 不会把你的 include 的数量算进去
我加了之后,返回的 count 果然正常了.