前言:放假前无心工作,只想给祖国过生日。钓鱼也有点意思:今天总结一下前几天写业务遇到的一个复杂的排序问题,记录下来分享给大家。1.业务场景由于涉及到公司内部的一些业务,为了避免一些奇怪的事情(你懂的)发生,这里只写下实现思路:需要后台查询数据库中的一些物料信息并返回显示,这是正常的像这样操作查询不是很难,只是这里的要求有点不同:首先材质的种类分为:默认材质(默认:1为默认,0isnormal)(默认只有)普通素材(vip:0)会员素材(vip:1)用户自定义素材(可能是会员素材也可能是普通素材)(因为每个用户自定义素材都不一样,在另一个用户-定义材质表:personal)然后,每个用户都可以自定义一个材质作为自己的封面。产品爸爸对排序的要求是:素材列表支持分页查询,每次用户请求返回这个素材列表:如果用户有自定义素材,先返回,否则按照默认顺序返回,即:当有是否自定义:自定义材质>默认材质>普通材质>成员材质没有自定义时:默认材质>普通材质>成员材质最后,材质的类型(默认,普通,成员)可以在管理后台,自定义素材由用户自行设置。正文:面对这样的排序功能,一开始我还比较淡定,暗自高兴:简单!思路是这样的:查询的时候使用mongoose的sort排序,按照default顺序和vip顺序倒序排列。排序列表为:默认材料>常用材料>成员材料。如果用户有自定义设置,二次查询,将自定义材质放在列表的最前面。由于自定义材质可能是default、common、member,所以在列表中同时查找并删除自定义材质,以保证列表中只有一个自定义材质。好的是:自定义材质>默认材质>普通材质>成员材质但是怎么分页,使用limit+offset会出现一个问题,就是:第一页数据:01234第二页数据:56789...at此时用户A正在浏览数据,当浏览到第一页时,用户B在第一页的数据中插入了一个item:X,此时:用户A看到的数据:第一页的数据:01234第二页的数据:45678...这样一来,当一个用户分页浏览数据时,其他用户插入数据,下一页的第一项就是上一页的最后一项。如果用户添加的操作过多,就会出现很多重复的数据。所以,对于分页,我一般使用sid分页的方式(随便找了一篇文章,我觉得sid的原理讲的很清楚,简单)。但是,使用sid分页,对所有素材进行排序,总是有点矛盾。最后说说最后的方法:这里多介绍一下管理后台和Redis的操作:在管理后台添加或修改素材时,查询一次数据库,按照:Default>General>Members排序检索数据,并收集数据有序Type将素材数据存储在Redis中:当用户没有自定义素材时,用户可以每次获取列表时查询Redis。当用户有自定义设置时,获取列表,将自定义放在0分位置,删除素材在此时排序集合中的位置:sid是排序组合中每个元素的分数。总结:这样做的好处是管理员在设置的时候会将排序后的物料列表存储在Redis中,不会出现分页数据重复的情况。本质上:用户每次只需要检查Redis,根据用户是否自定义了Set来做数组元素的插入和删除。
