Esfinge: Qual é a melhor maneira de corda aproximada classificação com vários índices?
Pergunta
Eu estou trabalhando com Esfinge e gostaria de implementar seqüência de ordenação. Eu entendo que isso pode ser feito usando atributos e Cordas Ordinals , no entanto, I também quer implementar vivo Índice Atualizações e ordinais cordas não funcionam com vários índices.
Qual seria a melhor maneira de corda aproximada classificação com vários índices? Estou pensando ao longo das linhas de gerar um número inteiro das primeiras letras da corda, por exemplo:
select concat(ord('t'),ord('e'),ord('s'));
me permita adicionar os três primeiros caracteres do string 'teste' para um atributo inteiro (supondo que ele seria adicionado à esfinge como um inteiro, embora seja uma string no MySQL). Isso me daria a classificação aproximada, que é provavelmente bom o suficiente.
Solução
I acabou criando uma função MySQL que converte a string para um ordinal:
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
A função utiliza apenas os quatro primeiros caracteres da cadeia, então a classificação será aproximada. Esta função é chamada durante a consulta esfinge indexação (no arquivo de configuração sphinx). O atributo é então utilizado para a classificação durante a chamada pesquisa esfinge.
Isso tem funcionado com sucesso em um ambiente de produção para mais de 6 meses.
Outras dicas
A resposta de jonstjohn me ajudou muito! Eu usei o código, mas não torná-lo em um UDF. Eu também converteu todas as strings em maiúsculas para que não haveria qualquer estranheza quando a classificação por ordem alfabética:
por isso acaba por ser algo como isto:
(..)
sql_query =
selecione \
id \
Nome \
((ORD (SUBSTRING (UPPER (nome), 1,1)) * 16777216) \
-
(ORD (SUBSTRING (UPPER (nome), 2,1)) * 65536) \
-
(ORD (SUBSTRING (UPPER (nome), 3,1)) * 256) \
-
(ORD (SUBSTRING (UPPER (nome), 4,1)))) como name_ord \
FROM \
minha_tabela
sql_attr_uint = name_ord
(..)
tanto para índices principais e delta.
Esteja ciente de que, por exemplo, ord ( 'e') é 38 e ord ( 'a') é de 97 por isso, se suas palavras são [az] [AZ] que é ok, mas se você tiver algo como h & b será antes hub por exemplo
Manfred