最近在思考在获取下一篇和上一篇的时候需要根据排序规则。 #406。但是发现,这个没有想象中这么简单。
问题
- 文章上下页的内容需要与文章列表页的顺序一致
- 文章列表页的排序顺序是可调整的。可以调整成按
创建时间
、最后编辑时间
、点击量
进行排序。 - 对于
创建时间
、最后编辑时间
可能无相同值的情况,但是对于点击量
,存在值相同但当前文章的排序位置未知的情况。 - 文章列表页需要兼容置顶文章。当计算上下篇文章时,置顶逻辑和自定义排序是对立的。
现有做法
首页
在sql层面通过排序规则解决,置顶优先级递减,自定义排序规则
文章详情页
在sql层面通过创建时间递减的规则展示
友商做法
Wordpress
在wp-includes/link-tempalte.php
下的get_adjacent_post
中。
$wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where")
"ORDER BY p.post_date $order LIMIT 1 "
$op = $previous ? '<' : '>';
$order = $previous ? 'DESC' : 'ASC';
核心根据post_date进行查询。未发现支持自定义排序的迹象
它将日期的比较操作以及排序做了逻辑控制。
如果是查上一篇,符号为<
,同时排序规则为 DESC
如果是查下一篇,符号为>
,同时排序规则为ASC
B3log Solo
下一页根据创建时间排序
未发现支持自定义排序的迹象
设计方案
方案一
拆分成置顶数据与普通数据两块。然后根据
拆分创建时间
、最后编辑时间
与访问量
的排序查询规则。
创建时间、最后编辑时间
通过逻辑确认比较字段(create_time
,edit_time
),比较符号(>
,<
),获取到符合要求的一条数据
访问量
比较字段为visits
,比较符号根据逻辑去人,获取到符合要求的并排序的所有数据,
通过逻辑找到当前的那条,然后获取其后一条数据。作为返回对象。
方案二
构造Page对象,与ArchiveContentController中的page方法一致的逻辑获取List,从List中找到文章的前后篇文章。
但是针对根据page获取数据,根据需要的数据做了部分的优化。 提了一个PR:Issue/406 next page sort #489
现阶段选择了方案二。
后续扩展
对于从分类中、或者标签中进入文章详情的情况。
整合几个调整点:
- getAdjacentPostList 增加返回对象{prePost:, nextPost: },同时在注释中明确返回对象描述。
- adjacentPostDTOList 是针对dev分支的改造做的调整,为了能返回fullPath,现在还不生效,会在dev稳定后重新适配。