2017-02-04 13 views
1

大きな文字列(ユーザー名、約350Kレコード)があります。私はそれを辞書順にソートして保存する必要があり、メンバーの存在*とメンバーの類似性**を効率的に取り出すことができなければなりません。 Redisソートセットは、ジョブのデータタイプのように見えます。大文字小文字のレキシカルソートセットで並べ替える場合

しかし、私は最初のハードルに落ちているようです。具体的には、私の重要な要件の1つは、同じ文字で始まる限り、異なる文字の場合を一緒に保つことです。例えば。 Benderbenderの両方が並んで注文されるはずです。しかしながら、redisのソートされたセットは、辞書編集順序規則に従って厳密であるため、大文字で始まるすべての文字列は、小文字で始まるすべての文字列の前にデフォルトでソートされます(例えば、はaの前に、ただしAの後に順序付けされます)。

これを回避する方法はありますか?また、要件を満たすために赤いソートセットを使用しますか?参考までに、私は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です。 BeNdからbend
  2. encoded name取得する小文字名にインデックスを追加します:bendbend0002から
  3. encoded nameを追加
  4. は小文字の名前を取得するために、下部ケースに名前の大文字に変換しますソートセットに:zadd key 0 bend0002
このように

BeNdbend並んで注文する必要があります。

検索を実行する場合は、同じエンコード方法を使用して指定された名前をエンコードし、検索して結果をデコードします。 encoded nameは大文字のインデックスを記録するので、簡単に解読できます。

+0

Clever。ユーザー名文字列に末尾の0が含まれているとどうなりますか?ユーザ名「Bender12300」を想像してみてください。 –

+0

@HassanBaigは、小文字の名前とインデックスの間の区切り文字として、どのユーザー名にも存在しない特殊文字を使用します。例:区切り文字として '-'を使用し、' Bender12300'を 'bender12300-00'としてエンコードします。 –

+0

@for_stack:上記の解決法は大文字と小文字を区別しない検索でも機能しますか? –

関連する問題