Сфинкс: Каков наилучший способ приблизительной сортировки строк с несколькими индексами? - PullRequest
1 голос
/ 10 марта 2009

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 30 декабря 2009

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

1 голос
/ 20 октября 2011

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

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

(..)

sql_query =

SELECT \

id \

имя \

((ORD (SUBSTRING (UPPER (имя), 1,1)) * 16777216) \

  • (ORD (ПОДПИСЬ (ВЕРХНЯ (имя), 2,1)) * 65536) \

  • (ORD (ПОДПИСЬ (ВЕРХНЯ (имя), 3,1)) * 256) \

  • (ORD (SUBSTRING (UPPER (имя), 4,1)))) как name_ord \

ОТ \

mytable

sql_attr_uint = name_ord

(..)

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

0 голосов
/ 24 марта 2009

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

Манфред

...