Foros del Web » Programando para Internet » PHP »

Motor de busqueda en base a diccionario

Estas en el tema de Motor de busqueda en base a diccionario en el foro de PHP en Foros del Web. Hola, les cuento la situacion tengo un diccionario en la base de datos para ayudar a un motor de busqueda en php, el diccionario tiene ...
  #1 (permalink)  
Antiguo 31/05/2010, 21:16
 
Fecha de Ingreso: septiembre-2009
Mensajes: 27
Antigüedad: 15 años, 1 mes
Puntos: 0
Pregunta Motor de busqueda en base a diccionario

Hola, les cuento la situacion tengo un diccionario en la base de datos para ayudar a un motor de busqueda en php, el diccionario tiene los campos id,dicpalabra, dicrelevancia,dictipo el tipo es para identificar categorias y agregar filtros desde php para "una gran sql". El problema es que al escribir palabras con algun error de escritura no encuentro resultados para el filtro.

Para aclarar un poco pongo un ej el usuario busca:
"Casa en punta del este para la venta"

El diccionario tiene:
- casa
- punta del este
- venta

Hasta este momento con mysql identifico los teminos contenidos en la frase así:
Código PHP:
select dicpalabra from diccionario where INSTR("Casa en punta del este para la venta",dicpalabra) >0 order by dicrelevancia DESC 
Esto es bastante efectivo, pero tiene sus defectos al tipear mal una palabra.
Si quisiera usar soundex para corregir haria esto:
Deberia hacer un explode separando por espacios " " y tendria este array:casa , en, punta, del, este, para, la, venta

Pero se me separan las palabras compuestas, "Punta del este" queda "Punta", "del", "este" y el diccionario tiene "punta del este" por lo tanto el soundex de "punta" no es igual de "punta del este" ni "del" y "este".

Algo que funcionaria de maravilla pero no se como hacerlo:
Insertar en la frase el soundex de cada palabra del diccionario y luego hacer el instr con soundex algo asi:

select dicpalabra from diccionario where instr("C000 en P53423 para la V530",soundex(dicpalabra)) >0
Entonces obtendria palabras que tengan el mismo soundex, y solucionaria algunos errores de tipeo

¿Se podria insertar el soundex de cada palabra en la frase sin perder palabras compuestas como Punta del este pero al mismo tiempo corregirlas ?

Desde ya gracias. Saludos !

Última edición por Brian_91; 31/05/2010 a las 21:28
  #2 (permalink)  
Antiguo 31/05/2010, 21:28
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Motor de busqueda en base a diccionario

Lo que podrías hacer es dividir también la frase "Punta del este" y verificar si todos los valores son iguales al que hiciste con el explode.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #3 (permalink)  
Antiguo 31/05/2010, 21:50
 
Fecha de Ingreso: septiembre-2009
Mensajes: 27
Antigüedad: 15 años, 1 mes
Puntos: 0
Respuesta: Motor de busqueda en base a diccionario

Cita:
Iniciado por abimaelrc Ver Mensaje
Lo que podrías hacer es dividir también la frase "Punta del este" y verificar si todos los valores son iguales al que hiciste con el explode.
Hola respuesta rapida , con mysql dividir la palabra del diccionario ??
Se podria con mysql extraer palabras de la frase separandolas por " " y concatenarlas con el respectivo soundex ?
  #4 (permalink)  
Antiguo 31/05/2010, 22:22
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Motor de busqueda en base a diccionario

Bueno, en MySQL no existe un split o explode, sí se puede hacer un "workaround" usando SUBSTRING_INDEX, como este ejemplo colocando en http://dev.mysql.com/doc/refman/5.0/...ons.html#c7380
Código MySQL:
Ver original
  1. `ip` ,
  2. SUBSTRING_INDEX( `ip` , '.', 1 ) AS a,
  3. SUBSTRING_INDEX(SUBSTRING_INDEX( `ip` , '.', 2 ),'.',-1) AS b,
  4. SUBSTRING_INDEX(SUBSTRING_INDEX( `ip` , '.', -2 ),'.',1) AS c,
  5. SUBSTRING_INDEX( `ip` , '.', -1 ) AS d
  6. FROM log_table
Tal vez con stored procedures, lo puedas lograr. Otra forma de hacerlo es descargar la tabla en un array en PHP y usar el explode y soundex de PHP.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #5 (permalink)  
Antiguo 01/06/2010, 12:25
 
Fecha de Ingreso: septiembre-2009
Mensajes: 27
Antigüedad: 15 años, 1 mes
Puntos: 0
De acuerdo Respuesta: Motor de busqueda en base a diccionario

Cita:
Iniciado por abimaelrc Ver Mensaje
Bueno, en MySQL no existe un split o explode, sí se puede hacer un "workaround" usando [URL="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index"]SUBSTRING_INDEX[/URL], como este ejemplo colocando en [url]http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#c7380[/url]
Código MySQL:
Ver original
  1. `ip` ,
  2. SUBSTRING_INDEX( `ip` , '.', 1 ) AS a,
  3. SUBSTRING_INDEX(SUBSTRING_INDEX( `ip` , '.', 2 ),'.',-1) AS b,
  4. SUBSTRING_INDEX(SUBSTRING_INDEX( `ip` , '.', -2 ),'.',1) AS c,
  5. SUBSTRING_INDEX( `ip` , '.', -1 ) AS d
  6. FROM log_table
Tal vez con [URL="http://dev.mysql.com/tech-resources/articles/mysql-storedprocedures.html"]stored procedures[/URL], lo puedas lograr. Otra forma de hacerlo es descargar la tabla en un array en PHP y usar el explode y soundex de PHP.
Gracias abimaelrc, voy a probar el substring_index y leer el pdf de stored procedures, pinta muy bien. Si encuentro la solucion la posteo
  #6 (permalink)  
Antiguo 01/06/2010, 19:54
 
Fecha de Ingreso: septiembre-2009
Mensajes: 27
Antigüedad: 15 años, 1 mes
Puntos: 0
Respuesta: Motor de busqueda en base a diccionario

Bueno despues, de probar ejemplos en el diccionario con 377 palabras no resulto muy util usar soundex, por que si bien encontraba esas palabras al escribirlas mal tambien me traia otras palabras del diccionario y la busqueda seria incoherente.

Al final lo voy hacer de esta forma:
Código PHP:
$sql="select dicpalabra, match(dicpalabra) against('".mysql_real_escape_string($query)."' IN BOOLEAN MODE) as score from diccionario having score > 0 and instr('".mysql_real_escape_string($query)."', dicpalabra)>0"
Mezclar full textsearch con instr, entonces las palabras que se escriban bien las voy a encontrar y las que tengan algun error de tipeo me las trae el full text search in boolean mode (escritas con cierto margen de error), pero incluso puede ser hasta mejor que el soundex, porque hay varias palabras con el mismo soundex mayormente palabras que tienen 5 o menos letras y sin espacios.

Sino encuentro resultados
Elimino palabras encontradas en el diccionario de la frase buscada y empieso a buscar con soundex las palabras que no encontre en el diccionario de esta forma:
Creo una nueva frase, que tiene el soundex() de cada palabra y las comparo contra el soundex de cada palabra en el diccionario.

Por ej: el soundex dentro del diccionario de "Punta del este" es "P530 D400 E230"

Entonces la sql seria:

select dicpalabra from diccionario where instr("C000 en P530 D400 E230",dicsoundex);
(palabras con menos de 2 letras no ingreso soundex en la frase, incluso es conveniente una lista de palabras a excluir como "en, el, para, con, sin".

Esa sql trae, "Punta del este", "casa" pero tambien tengo otras palabras como "chuy" que tiene el mismo soundex que "casa".

Para "armar el quizás quiso decir", tengo 2 cosas por hacer ordenar por relevancia las palabras obtenidas, y en el diccionario tengo un campo dictipo esto es para separar palabras, es una web de buscar propiedades y tengo los tipos:
categoria("venta,alquiler etc"), tipos("Casa, apartamento..."), Ubicacion("Cuidades, zonas.."), comodidad("Garage, piscina etc")
(El diccionario se alimenta de otras tablas, ciudades, zonas, atributos, categorias, y algunas ingresadas manualmente)

Entonces para armar una frase coherente y decirle al usuario "quizas quisiste decir", lo minimo que tengo que mostrar es el tipo de propiedad luego lo de mas es random:
TIPO +(ubicacion y/o categoria ) es el criterio que uso y si el usuario ingreso alguna comodidad la agrego al final de la frase.

Bueno espero le sirva a alguien. Si hay ideas para mejorar bienvenidas sean !!!

Última edición por Brian_91; 01/06/2010 a las 20:05
  #7 (permalink)  
Antiguo 01/06/2010, 20:14
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Motor de busqueda en base a diccionario

Como te indique, puedes ingresar la consulta en un array y usar las funciones de PHP. Te recomiendo que mires la función levenshtein, ahí hay un ejemplo de exactamente lo que te quiero decir y exactamente lo que tu quieres hacer.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #8 (permalink)  
Antiguo 05/06/2010, 18:37
 
Fecha de Ingreso: septiembre-2009
Mensajes: 27
Antigüedad: 15 años, 1 mes
Puntos: 0
Respuesta: Motor de busqueda en base a diccionario

Cita:
Iniciado por abimaelrc Ver Mensaje
Como te indique, puedes ingresar la consulta en un array y usar las funciones de PHP. Te recomiendo que mires la función [URL="http://www.php.net/manual/en/function.levenshtein.php"]levenshtein[/URL], ahí hay un ejemplo de exactamente lo que te quiero decir y exactamente lo que tu quieres hacer.
Ok, voy a probar esa funcion.

Etiquetas: diccionario, motor, busquedas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:18.