Strapi中实现文章分页的方法及相关技术问题咨询
Strapi 分页功能实现问题解答
底层是否使用Mongoose判断方法
Strapi数据库层支持多适配,是否使用Mongoose完全取决于你的项目配置,直接查看项目config/database.js文件中的client字段即可确认:
- 字段值为
mongo时,底层基于Mongoose连接MongoDB - 字段值为
mysql/postgres/sqlite时,底层基于Bookshelf(Knex)实现,和Mongoose无关
不建议直接通过.model获取底层原生模型实例写业务逻辑,后续升级Strapi、切换数据库时会出现兼容问题。
控制器参数传递到resolver的规则
不需要手动在控制器里透传参数到resolver,GraphQL执行流本身有固定的参数传递规则:
- 第一个参数
obj是上一级resolver返回的父级实体数据,你之前写的obj.limit、obj.offset是错误取值方式,父级对象里不会携带分页参数 - 第二个参数
options是当前请求携带的所有查询参数,控制器层接收到的ctx.query里的分页、筛选条件,都会自动解析到这个参数里,直接从这里取值即可 - 第三个参数
ctx是全局请求上下文,包含用户信息、请求头等公共数据
分页写法修正
你写的链式调用.limit().offset()存在三个问题:
- 分页参数取值位置错误,拿不到实际传入的分页值
- 直接调用原生模型方法不兼容非Mongo环境
- 返回值是
result.length > 0的布尔值,完全不符合分页接口返回数据的要求
正确实现代码
不管底层用什么数据库,优先调用Strapi官方封装的查询方法,自动适配ORM差异,写法如下:
resolver: async (obj, options, ctx) => { // 设置分页默认值,Strapi默认偏移量字段为start,不是offset const { limit = 10, start = 0 } = options; // 并行查询分页列表和总条数 const [data, total] = await Promise.all([ strapi.query('active').find({ article_id: obj.id, _limit: limit, _start: start }), strapi.query('active').count({ article_id: obj.id }) ]); // 返回标准分页结构 return { data, total, limit, start, hasMore: start + data.length < total } }
如果你确认项目100%使用Mongo+Mongoose,原生链式调用的语法本身可以运行,注意Mongoose中偏移推荐用.skip()和limit搭配,但是依然更推荐用上面的封装写法,避免后续维护问题。
另外你最开始写的REST控制器代码不需要修改,默认的strapi.services.article.find(ctx.query)本身已经支持分页,请求时携带_limit、_start参数即可自动完成分页,不需要额外加逻辑。
内容的提问来源于stack exchange,提问作者user11092881
相关产品推荐
相关产品推荐

