2009-01-02 26 views
8

Estoy trabajando en una página 'búsqueda avanzada' en un sitio donde ingresaría una palabra clave como 'Me gusta manzanas' y puede buscar en la base de datos usando las siguientes opciones:Php/MySql 'Búsqueda avanzada' Página

Encontrar: Con todas las palabras, con el frase exacta, con al menos uno de las palabras, sin las palabras

puedo cuidar de la 'frase exacta' por:

SELECT * FROM myTable WHERE field='$keyword'; 

'Al menos uno de los términos' por:

SELECT * FROM myTable WHERE field LIKE '%$keyword%';//Let me know if this is the wrong approach 

Pero es el 'Con al menos una de las palabras' y 'Sin las palabras' que estoy atascado en.

¿Alguna sugerencia sobre cómo implementar estos dos?

Editar: En cuanto a 'por lo menos una palabra' no sería un buen método para usar explotar() para romper las palabras clave en palabras, y ejecutar un bucle para agregar

(field='$keywords') OR ($field='$keywords) (OR).... 

Debido a que hay hay algunas otras cláusulas Y/O en la consulta también y no conozco la cantidad máxima de cláusulas que puede haber.

Respuesta

12

Sugeriría el uso de MySQL FullText Search usando esto con la funcionalidad Boolean Full-Text Searches para que pueda obtener el resultado deseado.

Editar:

ejemplo solicitada en función de sus condiciones solicitados ("Es sólo un campo y que pueden escoger cualquiera de las 4 opciones (es decir 1 palabra, palabras exactas, al menos 1 palabra, sin el término).")

estoy asumiendo que usted está usando PHP basado en su mensaje inicial

<?php 
$choice = $_POST['choice']; 
$query = $_POST['query']; 

if ($choice == "oneWord") { 
    //Not 100% sure what you mean by one word but this is the simplest form 
    //This assumes $query = a single word 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)"); 
} elseif ($choice == "exactWords") { 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('\"{$query}\"' IN BOOLEAN MODE)"); 
} elseif ($choice == "atLeastOneWord") { 
    //The default with no operators if given multiple words will return rows that contains at least one of the words 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('{$query}' IN BOOLEAN MODE)"); 
} elseif ($choice == "withoutTheTerm") { 
    $result = mysql_query("SELECT * FROM table WHERE MATCH (field) AGAINST ('-{$query}' IN BOOLEAN MODE)"); 
} 
?> 

esperanza esto ayuda para la plena utilización de los operadores en partidos booleanos ver Boolean Full-Text Searches

+0

+1, esta es la mejor respuesta, pero yo también detalle que el texto completo de MySQL sólo está disponible para las tablas MyISAM, no los innodb. Así que elegir entre consistencia o. búsqueda –

+0

transaccional Si das un poco de código fuente que muestra cómo se pueden hacer las dos características (es decir, todas las palabras y sin las palabras) con el texto completo no podría aceptar su respuesta. –

+0

yo sería feliz para ofrecerle un código de ejemplo. Si usted me puede decir hay dos campos separados en el formulario de búsqueda con y sin o ¿está utilizando un campo? Si se trata de un campo puede simplemente permitir que el usuario agregue las palabras que quiere excluir con un -. –

2

Usted podría utilizar

Con al menos una de las palabras

SELECT * FROM myTable WHERE field LIKE '%$keyword%' 
or field LIKE '%$keyword2%' 
or field LIKE '%$keyword3%'; 

Sin la palabra

SELECT * FROM myTable WHERE field NOT LIKE '%$keyword%'; 
+0

por favor ver mi texto de arriba. ¿Cree que esta es una buena solución, es decir, hay un límite en la cantidad de cláusulas OR que se pueden incluir en una consulta? –

+0

Probablemente exista un límite, pero nunca lo he alcanzado y he hecho mucho más tiempo en las sentencias, pero cuanto más agregue, más lenta será la consulta y 'me gusta 'es particularmente lento. – Re0sless

+0

No hay límite práctico. Si tiene otras cláusulas WHERE, corchetee la búsqueda de palabras clave: "DONDE algo = x AND (campo LIKE ... O campo LIKE ... OR ...) – Greg

2

No estoy seguro de que fácilmente podría hacer esas opciones de búsqueda en una ingenua manera como los otros dos.

Valdría la pena implementar un mejor motor de búsqueda si necesita admitir esos escenarios. Una simple que probablemente podría pasar por alto es algo así:

Cuando se agrega un elemento a la base de datos, se divide en las palabras individuales. En este punto, las palabras "comunes" (the, a, etc ...) se eliminan (probablemente en base a una tabla common_words). Las palabras restantes se agregan a una tabla de palabras si aún no están presentes. A continuación, se establece un enlace entre la palabra ingresada y la entrada del elemento.

Al realizar una búsqueda, se trata de obtener los identificadores de palabras de la tabla de palabras y la búsqueda adecuada de los identificadores de elementos en la tabla de unión.

1

búsqueda es muy difícil de hacer bien .

debe considerar el uso de un motor de búsqueda de terceros usando algo como Lucene o Sphider.

0

Giraffe y Re0sless pooseted 2 buenas respuestas.

notas: "SELECT *" chupa ... solamente seleccionar las columnas que usted necesita. Re0sless pone un "OR" entre las palabras clave. - que debe eliminar palabras comunes ("", 'i', 'mañana', 'y' .. etc) - MySQL tiene un 8 kb i belive límite en el tamaño de la consulta, por lo que para muy largo selecciona debe Slipt en consultas separadas. - trate de eliminar las palabras clave duplicadas (si busco "usted sabe que le gusta" el SELECT básicamente debería buscar "usted" una vez y eliminar palabras comunes como "eso")

También intente utilizar "LIKE" y "partido como" (ver página del manual de MySQL) que podría hacer maravillas para las búsquedas "fuzzy"

Cuestiones relacionadas