2017-02-04 52 views
1

我有一大串字符串(包含用戶名,約350K記錄)。我需要按照字典順序進行排序,並且應該能夠有效地檢索成員存在*和成員相似度**。 Redis排序集看起來像作業的數據類型。在redis排序集合中,案例不可知的字典排序

但是,我似乎在第一個障礙。具體而言,我的一個關鍵要求是將不同的信件集合在一起,只要它們以相同的字母開頭。例如。應該最終並排訂購Benderbender。但是,redis的排序集在遵循詞典排序規則時是嚴格的,因此所有以大寫字母開頭的字符串在所有以小寫字母開頭的字符串(例如Za之前,但在A之後排序)之前都被排序。

有什麼辦法可以解決這個問題,仍然使用redis排序集來滿足我的要求嗎?僅供參考,我使用redis 2.8.4版。提前致謝。


*成員存在:一個用戶名,檢查它是否已經存在於存儲的設定

**成員相似:一個用戶名,拉N個存儲的用戶名是最喜歡的給定用戶名

+2

請參閱[正常化大小寫和重音字符串](https://redis.io/topics/indexes#normalizing-strings-for-case-and-accents) – thepirat000

+0

@ thepirat000:這是一篇很棒的文章。唯一的問題是它利用了不適用於redis 2.8.4的ZRANGEBYLEX。我可以實現相同的早期版本:http://oldblog.antirez.com/post/autocomplete-with-redis.html,但這不是詞典不可知的。 –

回答

1

您需要使用名稱進行一些特殊編碼。以下是一個例子。

假設所有名字的長度小於100個字符。對於每個名稱,執行以下步驟對其進行編碼:的大寫字母

  1. 紀錄指數與2位:爲BeNd,該指數是0002
  2. 轉換名稱的大寫字母爲較低的情況下獲得一個小寫的名字:從BeNdbend
  3. 指數追加到小寫名稱,以獲得encoded name:從bendbend0002
  4. 添加encoded name進入有序set:zadd key 0 bend0002

這樣,BeNdbend應該並排訂購方。

如果要執行搜索,請使用相同的編碼方法對給定名稱進行編碼,執行搜索並對結果進行解碼。由於encoded name記錄大寫字母的索引,您可以輕鬆解碼。

+0

聰明。如果用戶名字符串包含結尾0,會發生什麼,例如想象一下用戶名「Bender12300」,比如? –

+0

@HassanBaig使用任何用戶名中不存在的特殊字符作爲小寫字母名稱和索引之間的分隔符。例如:使用'-'作爲分隔符,並將'Bender12300'編碼爲'bender12300-00' –

+0

@for_stack:以上解決方案是否也適用於不區分大小寫的搜索? –