Foros del Web » Programando para Internet » PHP »

Buscador interno y "mother of orthography" ( php + mysql )

Estas en el tema de Buscador interno y "mother of orthography" ( php + mysql ) en el foro de PHP en Foros del Web. Hola gente, hacen un buen tiempo que no paso por estos lados... En este caso mas que un problema es un proyecto... como todos sabemos ...
  #1 (permalink)  
Antiguo 22/10/2013, 09:57
 
Fecha de Ingreso: mayo-2009
Ubicación: Japon
Mensajes: 60
Antigüedad: 14 años, 11 meses
Puntos: 12
Buscador interno y "mother of orthography" ( php + mysql )

Hola gente, hacen un buen tiempo que no paso por estos lados...

En este caso mas que un problema es un proyecto...

como todos sabemos hoy por día, los internautas escriben "fatal" (la mayoría) , a tal nivel que da dolor de cabeza y molesta ver sus comentarios...

El topic es el siguiente, construir un sistema de búsqueda en php

Al decir vedad, estuve buscando en varios sitios y comunidades alguna solución, pero no encontré nada que fuese realmente relevante y funcione "bien", solo algunos comentarios que me han dado ideas.

algunas preguntas para iniciar el tema

es viable el proyecto o estoy perdiendo el tiempo?

estuve leyendo acerca de las "coliciones" de palabras aunque no pude allar un método que funcione... alguien tiene alguna fuente que hable acerca del tema? (no importa el lenguaje de programación)


desde ya muchas gracias
  #2 (permalink)  
Antiguo 22/10/2013, 10:01
Avatar de maycolalvarez
Colaborador
 
Fecha de Ingreso: julio-2008
Ubicación: Caracas
Mensajes: 12.120
Antigüedad: 15 años, 9 meses
Puntos: 1532
Respuesta: Buscador interno y "mother of orthography" ( php + mysql )

a lo sumo lo que podrías hacer es integrar la API de algún corrector ortográfico, que ya existen varios, incluso con php http://www.php.net/manual/es/refs.international.php.

el mejor ejemplo es google, que es capaz de sugerirte
__________________
¡Por favor!: usa el highlight para mostrar código
El que busca, encuentra...
  #3 (permalink)  
Antiguo 22/10/2013, 10:32
 
Fecha de Ingreso: mayo-2009
Ubicación: Japon
Mensajes: 60
Antigüedad: 14 años, 11 meses
Puntos: 12
Respuesta: Buscador interno y "mother of orthography" ( php + mysql )

interesante dato, aunque es algo distinto, ya que es un buscador interno

por ejemplo si vas con mysql y buscas algo con LIKE o AGAINST, si el usuario no escribe bien no regresa un resultado

por otro lado si utilizas un diccionario las palabras "claves" y siglas no son reconocidas, por lo que mi idea era "intentar crear un algoritmo de colisión basada en php" algo así como un implementacion hamming o algo por el estilo

había pensado en realizar un indexado de palabras internas, un "diccionario privado" por así decirlo... aunque no encuentro nada que me permita buscar "cercanías" entre una palabra y otra, por ejemplo:

si alguien escribe "escrip" y en el diccionario interno tengo "script", existe alguna librería o "forma" de retornar esa "posible sugerencia"



no se si me estoy explicando correctamente (de ser asi, mis disculpas)

es un topic "abierto", por lo que cualquier comentario o idea random es bienvenido

nota: estoy leyendo un poco acerca de la librera pspell, me llamo la atención
  #4 (permalink)  
Antiguo 22/10/2013, 11:17
Avatar de Cuervoo  
Fecha de Ingreso: octubre-2013
Mensajes: 165
Antigüedad: 10 años, 6 meses
Puntos: 43
Respuesta: Buscador interno y "mother of orthography" ( php + mysql )

Está bueno pero creo que sería bastante complicado de arrancar porque (por lo que se me viene a la cabeza ahora) lo que habría que hacer previamente es una estadística de todas las palabras que usan mal, ver el contexto y a raiz de eso tener una idea de qué carajo quisieron decir. Y con eso mostrarles una sugerencia que no va a ser el 100% de las veces la que quisieron decir pero si en la mayoría.

Está bueno para sentarse a pensar un rato, sobre todo como sacar el contexto de lo que están escribiendo.
  #5 (permalink)  
Antiguo 22/10/2013, 12:26
Colaborador
 
Fecha de Ingreso: mayo-2008
Ubicación: $MX['VZ']['Xalapa']
Mensajes: 3.005
Antigüedad: 15 años, 11 meses
Puntos: 528
Respuesta: Buscador interno y "mother of orthography" ( php + mysql )

Podrías intentar probando la distancia levenshtin, o con las funciones soundex o similar text. http://php.net/manual/es/function.levenshtein.php
  #6 (permalink)  
Antiguo 22/10/2013, 22:38
 
Fecha de Ingreso: mayo-2009
Ubicación: Japon
Mensajes: 60
Antigüedad: 14 años, 11 meses
Puntos: 12
Respuesta: Buscador interno y "mother of orthography" ( php + mysql )

muchas gracias por tomarse la molestia de responder!

Cita:
Iniciado por ocp001a Ver Mensaje
Podrías intentar probando la distancia levenshtin, o con las funciones soundex o similar text. [url]http://php.net/manual/es/function.levenshtein.php[/url]
genial el dato, es exactamente lo que estaba buscando, solo habría que ver como realizar generar el index de errores o mapeados de "mother of orthography"

Cita:
...sobre todo como sacar el contexto de lo que están escribiendo.
Estuve hablando con otras personas acerca de las políticas de privacidad y esas cosas en Internet, la cual "guardar las búsquedas" de los usuarios supone un "delito" (aunque me párese insólito)

Eliminando los posibles problemas se podría crear una base de datos con las keywords que no aya sido "encontradas" por los usuarios

De momento me pondré a hacer uno que otro test, cuando tenga algún avance, publico. si alguien consigue hacer "algo", toda idea/aporte es bienvenid@
  #7 (permalink)  
Antiguo 24/10/2013, 08:03
 
Fecha de Ingreso: mayo-2009
Ubicación: Japon
Mensajes: 60
Antigüedad: 14 años, 11 meses
Puntos: 12
Respuesta: Buscador interno y "mother of orthography" ( php + mysql )

Cita:
Iniciado por ocp001a Ver Mensaje
Podrías intentar probando la distancia levenshtin, o con las funciones soundex o similar text. [url]http://php.net/manual/es/function.levenshtein.php[/url]
nose si alguien habrá seguido el post pero bueh...

comenzamos con el código

gracias a ocp001a y su aporte me puse a investigar un poco, la verdad no esperaba tan buenos resultados (toca filtrar un poco) ya que en cierta forma otorga bastantes resultados basuras...

en si el código esta "vivo" y lo he testeado "un poco", no se rían de mi forma de programar, comenten de forma constructiva!

basta de blablas... a ver un poco de source!


la librería "class.php", es algo un poco "primitiva" aunque indexa correctamente (en varios casos mejor que like y against), decidí meterlo todo dentro de una clase para que fuese un poco mas ordenada, la función "install" la puse simplemente porque existe quienes no saben como subir un .sql


nota: la librería mysql "tradicional" fue declarada deprecada, creo que algunos no están muy familiarizados con las librerías mysqli o PDO por tal causa decidí usar la librería tradicional, simplemente para que todos puedan seguir el hilo


Código PHP:
<?php

class index
{
    private 
$mysqlr;
    
//la clase constructora
    
public function __construct($host$user$pass$db)
    {
        
//creamos una conexion y almacenamos el identificador
        
$this->mysqlr mysql_connect($host$user$pass) or die(mysql_error());
        
        
//cambiamos la encodificacion a utf8
        
mysql_query('SET NAMES utf8') or die(mysql_error());
        
        
//seleccionamos la base de datos
        
mysql_select_db($db) or die(mysql_error());
    }
    
    
    public function 
__desctruct()
    {
        
//desconectamos el mysql
        
mysql_close($this->mysqlr);
    }
    
    
    public function 
save($txt$minLen 2)
    {
        
// prevenir las llamadas sin conexion
        
if(!isset($this)){ return false; }
        
        
//multibite en utf8
        
mb_internal_encoding("UTF-8");

        
//remplasar delimitadores por un espacio
        
$txt str_replace(array("."'"'"'"','':'';''@''/''\\'"\n""\r""\t""[""]""("")") , ' '$txt);
        
        
//convertir la cadena de texto en una matris
        
$txt explode(' '$txt);
        
        
$values '';
        
//recorrer cada palabra y agregarla al index
        
foreach($txt as $keyword)
        {
            
//comprobar que supera la longitud minina
            
if(mb_strlen($keyword) >= $minLen)
            {
                
$values .= ($values != '' ', ' '')."('$keyword')";
            }
        }
        
        
//echo "INSERT IGNORE INTO `lib_post_index` (`key`) VALUES $values";
        
if($values != '')
        {
            
mysql_query("INSERT IGNORE INTO `lib_post_index` (`key`) VALUES $values"$this->mysqlr) or die(mysql_error());
        }
    }
    
    
    public function 
check($key$sens 2)
    {
        
// prevenir las llamadas sin conexion
        
if(!isset($this)){ return false; }
        
        if(
$query mysql_query("SELECT *, levenshtein('$key', `key`) AS `lvs` FROM `lib_post_index` WHERE levenshtein('$key', `key`) BETWEEN 0 AND $sens ORDER BY `lvs`, `key` ASC"))
        {
            return 
$query;
        }
    }
    
    
    public function 
install()
    {
        
// prevenir las llamadas sin conexion
        
if(!isset($this)){ return false; }
        
        
//comprobar que la funcion no exista y luego instalar;
        
$result mysql_query("SHOW FUNCTION STATUS LIKE 'levenshtein'") or die(mysql_error());
        
        if(
mysql_num_rows($result) == 0)
        {
            
mysql_query("CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
              RETURNS INT
              DETERMINISTIC
              BEGIN
                DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
                DECLARE s1_char CHAR;
                -- max strlen=255
                DECLARE cv0, cv1 VARBINARY(256);
                SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
                IF s1 = s2 THEN
                  RETURN 0;
                ELSEIF s1_len = 0 THEN
                  RETURN s2_len;
                ELSEIF s2_len = 0 THEN
                  RETURN s1_len;
                ELSE
                  WHILE j <= s2_len DO
                    SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
                  END WHILE;
                  WHILE i <= s1_len DO
                    SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
                    WHILE j <= s2_len DO
                      SET c = c + 1;
                      IF s1_char = SUBSTRING(s2, j, 1) THEN 
                        SET cost = 0; ELSE SET cost = 1;
                      END IF;
                      SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
                      IF c > c_temp THEN SET c = c_temp; END IF;
                        SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
                        IF c > c_temp THEN 
                          SET c = c_temp; 
                        END IF;
                        SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
                    END WHILE;
                    SET cv1 = cv0, i = i + 1;
                  END WHILE;
                END IF;
                RETURN c;
              END;"
) or die(mysql_error());
             
              
mysql_query("CREATE FUNCTION levenshtein_ratio( s1 VARCHAR(255), s2 VARCHAR(255) )
              RETURNS INT
              DETERMINISTIC
              BEGIN
                DECLARE s1_len, s2_len, max_len INT;
                SET s1_len = LENGTH(s1), s2_len = LENGTH(s2);
                IF s1_len > s2_len THEN 
                  SET max_len = s1_len; 
                ELSE 
                  SET max_len = s2_len; 
                END IF;
                RETURN ROUND((1 - LEVENSHTEIN(s1, s2) / max_len) * 100);
              END;"
) or die(mysql_error());
              
              
              
mysql_query("CREATE TABLE IF NOT EXISTS `lib_post_index` (
              `id` bigint(20) NOT NULL AUTO_INCREMENT,
              `key` varchar(255) DEFAULT NULL,
              `parents` text CHARACTER SET ascii,
              PRIMARY KEY (`id`),
              UNIQUE KEY `key` (`key`)
            ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"
) or die(mysql_error());
        }
    }
}
?>
fuente "function levenshtein" -> http://stackoverflow.com/questions/4671378/levenshtein-mysql-php

dentro de todo allí esta lo mas importante, la función levenshtein ella retornara los elementos que contengan mas cercanía a la palabra clave

la función save "parsea" el texto según los delimitadores indicados y retorna un array, el loop genera la query y el mysql_query los guarda en la tabla "lib_post_index"

en si es todo esta bastante fácil de entender creo...


index.php esta es una interface muy precaria pero para testear sobra

Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<?php
//incluimos la clase principal
include 'class.php';

//creamos el objeto
$index = new index('localhost''usuario mysql''password mysql''base de datos');

//comprobamos que alla datos suficientes como para guardar el string
if(isset($_POST['string']) && strlen($_POST['string']) > 2)
{
    
//creamos el index
    
$index->save($_POST['string']);
}

// comprobamos si hay una keyword
if(isset($_POST['keyword']))
{
    
//generamos una consulta
    
$query $index->check($_POST['keyword'], 2);
    
    
//imprimimos el/los resultado(s)
    
while($_result mysql_fetch_assoc($query))
    {
        
print_r($_result);
        echo 
'<br />';
    }
}

?>

<body>

<form method="post" enctype="multipart/form-data">
    buscar en el index<br />
    <input name="keyword" type="text" value="<?php echo $_POST['keyword']; ?>" /><br /><br />
    
    indexar texto<br />
    <textarea name="string"></textarea><br />
    <input type="submit" />
</form>

</body>
</html>
comenten cualquier idea o algo que se les ocurra para optimizar el codigo, "maten a los que den copy&past" haha

Última edición por nksn; 24/10/2013 a las 08:09 Razón: error de redaccion

Etiquetas: buscador, interno, mother, mysql
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:10.