1

我正在使用Sphinx并希望实现字符串排序。我知道这可以使用属性和String Ordinals来完成,但是,我还想实现实时索引更新,并且字符串序数不适用于多个索引。

使用多个索引近似字符串排序的最佳方法是什么?我正在考虑从字符串的前几个字母生成整数,例如:

select concat(ord('t'),ord('e'),ord('s'));

将允许我将字符串“test”的前三个字符添加到整数属性(假设它将作为整数添加到 sphinx,即使它是 MySQL 中的字符串)。这会给我近似排序,这可能已经足够好了。

4

3 回答 3

3

我最终创建了一个将字符串转换为序数的 MySQL 函数:

CREATE DEFINER=`root`@`localhost` 
    FUNCTION `stringToOrd`(str varchar(100)) RETURNS int(11)
READS SQL DATA
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN

    DECLARE ordinal INT;
    SELECT ((ORD(SUBSTRING(str,1,1)) * 16777216) 
        + (ORD(SUBSTRING(str,2,1)) * 65536)
        + (ORD(SUBSTRING(str,3,1)) * 256) + (ORD(SUBSTRING(str,4,1)))) 
        into ordinal;
    return ordinal;
END 

该函数仅使用字符串的前四个字符,因此排序将是近似的。在 sphinx 索引查询期间调用此函数(在 sphinx 配置文件中)。然后在 sphinx 搜索调用期间使用该属性进行排序。

这已经在生产环境中成功运行了 6 个多月。

于 2009-12-30T20:27:14.663 回答
1

jonstjohn 的回答对我帮助很大!我使用了他的代码,但没有将其变成 UDF。我还将所有字符串都转换为大写,因此在按字母顺序排序时不会有任何奇怪:

所以结果是这样的:

(..)

sql_query =

选择 \

ID \

姓名 \

((ORD(SUBSTRING(UPPER(name),1,1)) * 16777216) \

  • (ORD(SUBSTRING(UPPER(name),2,1)) * 65536) \

  • (ORD(SUBSTRING(UPPER(name),3,1)) * 256) \

  • (ORD(SUBSTRING(UPPER(name),4,1)))) 作为 name_ord \

从 \

我的表

sql_attr_uint = name_ord

(..)

对于主索引和增量索引。

于 2011-10-20T15:31:45.577 回答
0

请注意,例如 ord('&') 是 38 和 ord('a') 是 97 所以如果你的话是 [az][AZ] 没关系,但如果你有像 h&b 这样的东西,例如它会在 hub 之前

曼弗雷德

于 2009-03-24T14:33:36.147 回答