假期前,无意工做,心中只想为祖国母亲庆生。摸鱼也要有点意义:今天就来总结下前几天在写业务的时候遇到一个比较复杂的排序问题,记录在这里与你们分享。数据库
因为涉及公司的一些内部业务,为避免一些奇奇怪怪的事情(你懂得)发生,我在这里只写下实现思路: 数据库中的一些素材信息
须要后端查询并返回展现,正常的相似这种查询操做业务不是很难,这里的需求有点不同: 首先:segmentfault
而后,每一个用户能够自定义一种素材做为本身的封面,产品爸爸对排序的要求是:素材列表支持分页查询,用户每次请求返回这个素材列表的时候:若是用户有自定义素材,优先返回,不然按照默认的顺序返回,即: 当有自定义时:用户自定义素材 > 默认素材 > 普通素材 > 会员素材 当无自定义时:默认素材 > 普通素材 > 会员素材后端
最后,素材的类型(默认、普通、会员)可在管理后台设置,用户自定义素材由用户设置。数组
面对这样一个排序功能,我一开始仍是比较淡定的,心中窃喜:简单!思路奉上: 查询的时候用 Mongoose
的 sort
排序,按照 ** default
逆序、vip
顺序 的方式排列, 排好的list
就是:默认素材 > 普通素材 > 会员素材, 若是用户有自定义设置,来一个二次查询,把自定义素材**放到 list
最前面,因为用户自定义的素材多是默认、普通、会员,因此同时找到删掉 list
中的自定义素材,这样就确保自定义素材在 list
中只有一个, 排好的就是:用户自定义素材 > 默认素材 > 普通素材 > 会员素材code
可是,分页怎么作呢,用 limit
+ offset
这样会出现一个问题,就是:排序
第一页数据:01234 第二页数据:56789 ...ip
这时候,A 用户在浏览数据,浏览到第一页时,B 用户往第一页数据插入一条:X,此时此刻: A 用户看到的数据:get
第一页数据:01234 第二页数据:45678 ...产品
这样就致使当用户在分页浏览数据时,有别的用户插入数据,下一页的第一条 是 上一页的最后一条,若是用户的添加操做过多,会出现不少重复的数据。it
因此,对于分页,我通常用的是 sid 分页的方法(随意找了一篇文章,我以为 sid 的原理说清楚了,简单就是)。
可是,既要用 sid
分页,又要对全部素材排序,总让人以为有点矛盾。
这里多了管理后台
和 Redis
的操做: 在运营在管理后台添加或者修改素材的时候,查询一次数据库,按照:默认 > 普通 > 会员 排序取出,以 有序集合
的数据类型将素材数据存入Redis
:
当用户无自定义素材时,用户每次获取 list
查询 Redis
就好
当用户有自定义设置时候,获取 list
,将自定义放到 0
分数位置,并删除该素材在有序集合中的位置
此时:sid
就是有序结合的每一个元素的分数。
Redis
,不会出现分页数据重复的状况Redis
, 根据用户是否有自定义设置来作数组元素的插入与删除。