Sphinx: ¿Cuál es la mejor manera de aproximar la ordenación de cadenas con múltiples índices?

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

  •  08-07-2019
  •  | 
  •  

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.

¿Fue útil?

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

¡La respuesta de Jonstjohn me ayudó mucho! Usé su código pero no lo convertí en un UDF. También convertí todas las cadenas a mayúsculas para que no hubiera ninguna rareza al ordenar alfabéticamente:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top