2017-02-04 53 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:以上解决方案是否也适用于不区分大小写的搜索? –