Mongoose + Redis 讓分頁與排序共存

序:

假期前,無意工做,心中只想爲祖國母親慶生。摸魚也要有點意義:今天就來總結下前幾天在寫業務的時候遇到一個比較複雜的排序問題,記錄在這裏與你們分享。數據庫

1. 業務場景

因爲涉及公司的一些內部業務,爲避免一些奇奇怪怪的事情(你懂得)發生,我在這裏只寫下實現思路: 數據庫中的一些素材信息須要後端查詢並返回展現,正常的相似這種查詢操做業務不是很難,這裏的需求有點不同: 首先:segmentfault

  • 素材種類分爲:
    • 默認素材(default:1爲默認,0爲正常)(默認惟一)
    • 普通素材(vip:0)
    • 會員素材(vip:1)
    • 用戶自定義的素材(多是會員素材也多是普通素材)(因爲每一個用戶自定義不同,在另一張用戶自定義素材表:personal)

而後,每一個用戶能夠自定義一種素材做爲本身的封面,產品爸爸對排序的要求是:素材列表支持分頁查詢,用戶每次請求返回這個素材列表的時候:若是用戶有自定義素材,優先返回,不然按照默認的順序返回,即: 當有自定義時:用戶自定義素材 > 默認素材 > 普通素材 > 會員素材 當無自定義時:默認素材 > 普通素材 > 會員素材後端

最後,素材的類型(默認、普通、會員)可在管理後臺設置,用戶自定義素材由用戶設置。數組

正文:

面對這樣一個排序功能,我一開始仍是比較淡定的,心中竊喜:簡單!思路奉上: 查詢的時候用 Mongoosesort 排序,按照 ** 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 就是有序結合的每一個元素的分數。

總結:

  1. 這樣作的好處是管理人員在設置的時候就將排好序的素材列表存入 Redis,不會出現分頁數據重複的狀況
  2. 本質上:用戶每次只須要查 Redis, 根據用戶是否有自定義設置來作數組元素的插入與刪除。

原文連接:segmentfault.com/a/119000002…

相關文章
相關標籤/搜索