Сфинкс:Каков наилучший способ приблизительной сортировки строк с несколькими индексами?

StackOverflow https://stackoverflow.com/questions/631729

  •  08-07-2019
  •  | 
  •  

Вопрос

Я работаю с Сфинкс и хотел бы реализовать сортировку строк.Я понимаю, что это может быть достигнуто с помощью атрибутов и Порядковые номера строк, однако, я также хочу реализовать Текущие обновления индекса а строковые ординалы не работают с несколькими индексами.

Каков был бы наилучший способ приблизительной сортировки строк с несколькими индексами?Я подумываю о том, чтобы сгенерировать целое число из первых нескольких букв строки, например:

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

это позволило бы мне добавить первые три символа строки 'test' к целочисленному атрибуту (предполагая, что он будет добавлен в sphinx как целое число, даже если это строка в MySQL).Это дало бы мне приблизительную сортировку, которая, вероятно, достаточно хороша.

Это было полезно?

Решение

В итоге я создал функцию 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). Атрибут затем используется для сортировки во время поискового вызова сфинкса.

Это успешно работает в производственной среде уже более 6 месяцев.

Другие советы

ответ Джонстджона мне очень помог!Я использовал его код, но не превратил его в UDF.Я также преобразовал все строки в верхний регистр, чтобы не было никаких странностей при сортировке по алфавиту:

итак, получается что-то вроде этого:

(..)

sql_query =

ВЫБЕРИТЕ \

ID \

Имя \

((ORD(ПОДСТРОКА(ВЕРХНЕЕ(имя),1,1)) * 16777216) \

  • (ORD(ПОДСТРОКА(ВЕРХНЕЕ(имя),2,1)) * 65536) \

  • (ORD(ПОДСТРОКА(ВЕРХНЕЕ(имя),3,1)) * 256) \

  • (ORD(ПОДСТРОКА(ВЕРХНИЙ(name),4,1)))) как name_ord \

От \

мой стол

sql_attr_uint = имя_корда

(..)

как для основного, так и для дельта-индексов.

Имейте в виду, что, например, ord ('&') равен 38, а ord ('a') равен 97, поэтому, если ваши слова [a-z] [A-Z], это нормально, но если у вас есть что-то вроде h & b, это будет, например, перед hub

Манфред

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top