Sphinx: ¿Cuál es la mejor manera de aproximar la ordenación de cadenas con múltiples índices?
Pregunta
Estoy trabajando con Sphinx y me gustaría implementar la clasificación de cadenas. Entiendo que esto se puede lograr usando atributos y Ordenales de cadena , sin embargo, yo también quiero implementar Actualizaciones de índice en vivo y los ordinales de cadena no funcionan con múltiples índices.
¿Cuál sería la mejor manera de aproximar la clasificación de cadenas con múltiples índices? Estoy pensando en la línea de generar un número entero a partir de las primeras letras de la cadena, por ejemplo:
select concat(ord('t'),ord('e'),ord('s'));
me permitiría agregar los primeros tres caracteres de la cadena 'prueba' a un atributo entero (suponiendo que se agregaría a sphinx como un entero aunque sea una cadena en MySQL). Esto me daría una clasificación aproximada, que probablemente sea lo suficientemente buena.
Solución
Terminé creando una función MySQL que convierte la cadena en un 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
La función solo usa los primeros cuatro caracteres de la cadena, por lo que la clasificación será aproximada. Esta función se llama durante la consulta de indexación de sphinx (en el archivo de configuración de sphinx). El atributo se utiliza para ordenar durante la llamada de búsqueda de esfinge.
Esto ha funcionado con éxito en un entorno de producción durante más de 6 meses.
Otros consejos
por lo que resulta ser algo como esto:
(..)
sql_query =
SELECCIONAR \
id \
nombre \
((ORD (SUBSTRING (UPPER (name), 1,1)) * 16777216) \
-
(ORD (SUBSTRING (SUPERIOR (nombre), 2,1)) * 65536) \
-
(ORD (SUBSTRING (SUPERIOR (nombre), 3,1)) * 256) \
-
(ORD (SUBSTRING (UPPER (name), 4,1)))) como name_ord \
DE \
mytable
sql_attr_uint = name_ord
(..)
tanto para los índices principales como para los delta.
Tenga en cuenta que, por ejemplo, ord ('& amp;') es 38 y ord ('a') es 97, por lo que si sus palabras son [az] [AZ] está bien, pero si tiene algo como h & amp; b, lo hará estar antes del hub, por ejemplo
Manfred