2011-03-04 13 views
9

Tengo palabras clave como "alguna que otra" donde los guiones importan en la búsqueda a través de mi base de datos mysql. Actualmente estoy usando la función de texto completo.Cómo permitir la búsqueda de texto completo con guiones en la consulta de búsqueda

¿Hay alguna manera de escapar del carácter de guion? Sé que una opción es comentar #define HYPHEN_IS_DELIM en el archivo myisam/ftdefs.h, pero desafortunadamente mi host no permite esto. ¿Hay otra opción por ahí?

Editar 08/03/11 Aquí está el código que tengo en este momento:

$search_input = $_GET['search_input']; 
$keyword_safe = mysql_real_escape_string($search_input); 
$keyword_safe_fix = "*'\"" . $keyword_safe . "\"'*"; 


$sql = " 
    SELECT *, 
     MATCH(coln1, coln2, coln3) AGAINST('$keyword_safe_fix') AS score 
     FROM table_name 
    WHERE MATCH(coln1, coln2, coln3) AGAINST('$keyword_safe_fix') 
    ORDER BY score DESC 
"; 

Respuesta

13

Desde aquí http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Una solución para encontrar una palabra con guiones o guiones en es utilizar TEXTO COMPLETO BÚSQUEDA EN MODO BOOLEANO, y para encerrar la palabra con el guión/guión entre comillas dobles.

O de aquí http://bugs.mysql.com/bug.php?id=2095

Hay otra solución. Se agregó recientemente al manual: " Modificar un archivo de conjunto de caracteres: Esto no requiere ninguna recompilación. La macro true_word_char() usa una tabla de" tipo de caracteres "para distinguir letras y números de otros caracteres . Puede editar el contenidos en uno de los archivos juego de caracteres XML para especificar que '-' es una continuación, utilizar el conjunto de caracteres para sus índices FULLTEXT "

no lo he probado en mi propia“carta”...

Editar: Aquí hay alguna información adicional más de aquí http://dev.mysql.com/doc/refman/5.0/en/fulltext-boolean.html

Una frase que está entre comillas dobles (“"”) caracteres partidos sólo las filas que contienen la frase literalmente, como si se hubiera escrito El completo. motor de texto divide la frase en palabras y realiza una búsqueda en el índice FULLTEXT para las palabras. Antes de MySQL 5.0.3, el motor realizaba una búsqueda de subcadena para la frase en los registros que se encontraron, por lo que la coincidencia debe incluir caracteres que no sean palabras en la frase. A partir de MySQL 5.0.3, los caracteres que no son palabras no tienen que coincidir exactamente: la búsqueda de frases requiere solo que las coincidencias contengan exactamente las mismas palabras que la frase y en el mismo orden. Por ejemplo, "frase de prueba" coincide con "prueba, frase "en MySQL 5.0.3, pero no se delantero.

Si la frase no contiene palabras que están en el índice, el resultado está vacío. Por ejemplo, si todas las palabras son palabras vacías o más cortas que la longitud mínima de las palabras indexadas, el resultado está vacío.

+0

De hecho, noté la primera solución que mencionaste. Sin embargo, no pude replicarlo. ¿Me puede dar un ejemplo de tal consulta? – Jay

+2

Claro, intente SELECCIONAR * FROM su_nombre_tabla DONDE COINCIDE (su_tabla_nombre_columna) EN CONTRA ('' SQL-MySQL '' EN MODO BOOLEANO); Consulte aquí para obtener más información http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html –

+0

FANTASTIC !! ¡Trabajado como un encanto! Muchas gracias :) – Jay

3

Quizás más simple de usar el operador Binary.

SELECT * 
FROM your_table_name 
WHERE BINARY your_column = BINARY "Foo-Bar%AFK+LOL" 

http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html#operator_binary

El operador BINARY convierte la cadena siguiente en una cadena binaria. Esta es una manera fácil de forzar una comparación de columna que se realiza byte por byte en lugar de carácter por carácter. Esto hace que la comparación sea sensible a mayúsculas y minúsculas, incluso si la columna no está definida como BINARY o BLOB. BINARY también causa que los espacios finales sean significativos.

+1

Esto provocó que MySQL Workbench se bloqueara por mí. – mnutsch

2

Algunas personas sugieren utilizar la siguiente consulta:

SELECT id 
FROM texts 
WHERE MATCH(text) AGAINST('well-known' IN BOOLEAN MODE) 
HAVING text LIKE '%well-known%'; 

Pero por que necesita muchas variantes dependiendo de los operadores utilizados en texto completo. Tarea: realizar una consulta como +well-known +(>35-hour <39-hour) working week*. Demasiado complejo!

Y no olvides la len por defecto de ft_min_word_len por lo que una búsqueda de up-to-date devuelve solo date en tus resultados.

truco

Debido a que prefiero un truco tan construcciones con HAVING etc no son necesarios en absoluto:

  1. En lugar de agregar el siguiente texto en su tabla de base de datos:

    "The Up-to-Date Sorcerer" is a well-known science fiction short story.
    copia las palabras de guión sin hiperas hasta el final del texto dentro de un comentario:
    "The Up-to-Date Sorcerer" is a well-known science fiction short story.<!-- UptoDate wellknown -->

  2. Si los usuarios buscan up-to-date quitar el guión en la consulta SQL:
    MATCH(text) AGAINST('uptodate ' IN BOOLEAN MODE)

Por que eres usuario puede encontrar up-to-date como una sola palabra en lugar de obtener todos los resultados que contienen sólo date (porque ft_min_word_len mata up y to).

Por supuesto delante de usted echo los textos que debe eliminar los comentarios <!-- ... -->.

Ventajas

  • la consulta es más simple
  • el usuario es capaz de utilizar todos los operadores de texto completo como de costumbre
  • la consulta es más rápido.
  • Si un usuario busca -well-known +science MySQL lo trata como not include *well*, could include *known* and must include *science*. Esto no es lo que el usuario esperaba. El truco resuelve que, también (como la consulta SQL busca -wellknown +science)
0

Esto puede sonar fuera, pero después de luchar con esto durante un tiempo, me di cuenta que tenga los resultados que deseo para retirando el guión de la expresión de búsqueda. Por ejemplo, si busco 'separados por palabras'

SELECT * FROM table WHERE MATCH(column) AGAINST ('word separated'); 

devuelve instancias de 'separadas por palabras' según sea necesario. Esto también devuelve otras instancias de separadas y palabras, pero al agregar el operador + a cada palabra se logra la búsqueda de guiones.

SELECT * FROM table WHERE MATCH(column) AGAINST ('+word +separated'); 
Cuestiones relacionadas