[AYUDA] Queries de caracteres acentuados en Postgres

Ixcoatl Perez ixcoatl.perez.de.la.b en gmail.com
Lun Abr 4 22:24:00 CDT 2011


La opcion de Paynalton es la que mas me gusta.

Es extremadamente facil de implementar del lado del cliente o servidor
y en cualquier lenguaje.
No necesitas mas que las vocales si usas un like y por supuesto, los
numeros son solo un lujo (A = 4).

Lo malo es que las expresiones regulares cuestan CPU, y son caras ! :D
Pero la trivialidad de la solucion lo justifica.



Saludos


El día 4 de abril de 2011 22:14, Paynalton <cxescalona en gmail.com> escribió:
> mmm, pero con regexp, la busqueda maria quedaría convertida a:
> select * from tabla where nombre similar to [mM][aAáÁäÄ][rR][iIíÍïÏ][aAáÁäÄ]
> lo cual haría match con:
> María
> maria
> Marïa
> mARIA
> incluso podrías poner:
> [mM][aAáÁäÄ4][rR][iIíÍïÏ1][aAáÁäÄ4]
> y coinsidiría con:
> M4r14
> Por eso me encantan las expresiones regulares jejjeje.
> Si un ave no rompe su huevo morirá antes de nacer.
> Nosotros somos el ave y el mundo es nuestro huevo.
> POR LA REVOLUCIÓN DEL MUNDO!!!!
>
> Ciudad de México
>
>
> El 4 de abril de 2011 19:16, Mario Benitez <mariobenitez en hotmail.com>
> escribió:
>>
>> Pudiera ser, pero por ejemplo
>>
>> Si la cadena de búsqueda es 'maría', y en la cual se sustituye 'í' por
>> 'i', si tendremos de regreso los resultados:
>>
>> maría
>> MARÍA
>> María
>> maria
>>
>> ... peeeero, si la cadena de búsqueda es 'maria', no habrá nada
>> sustituíble, por lo que los resultados de la búsqueda serán:
>>
>> maria
>>
>> Ahora estoy probando habilitar TSearch2 en postgres. Les cuento a ver que
>> tal.
>>
>> Saludos.
>>
>> ________________________________
>> From: cxescalona en gmail.com
>> Date: Mon, 4 Apr 2011 18:29:08 -0500
>> Subject: Re: [AYUDA] Queries de caracteres acentuados en Postgres
>> To: ayuda-linux en googlegroups.com
>>
>> oye, y no podrás usar acaso un regexp para refinar tus búsquedas??
>>
>> http://www.postgresql.org/docs/8.3/static/functions-matching.html
>>
>> segun esto puedes usar la función similar to:
>>
>> select * from tabla where nombre similar to maria
>>
>>
>> que además soporta expresiones regulares
>>
>>
>> si así solo no te funciona puedes por ejemplo a tu cadena de búsqueda
>> reemplazarle cada caracter por una regla como a="[aAáÁäÁ]" m="[mM]" y así
>> antes de integrarla a tu query, ademásde convertirla a la codificación de
>> carácteres que estes manejando en tus tablas.
>>
>> Si un ave no rompe su huevo morirá antes de nacer.
>> Nosotros somos el ave y el mundo es nuestro huevo.
>> POR LA REVOLUCIÓN DEL MUNDO!!!!
>>
>> Ciudad de México
>>
>>
>> El 4 de abril de 2011 17:06, Gustavo Guillermo Perez
>> <gustavo en compunauta.com> escribió:
>>
>> El Lunes 04 Abril 2011, Ixcoatl Perez escribió:
>> > Si, asi es.
>> >
>> > Lo que queria decir es la velocidad de ejecucion por cada registro es
>> > comprable a la de un 'like' , por decir algo. Ambos tienen que hacer
>> > sustituciones internas de un buffer en la memoria para cada llamada a
>> > la funcion.
>> >
>> > Asi las cosas tu programa puede ser que no se vea afectado grandemente
>> > por esta situacion.
>> >
>> > De cualquier manera, si estas hablando de sacar millones de registros
>> > de una tabla, la transposicion de unos cuantos bytes sera el menor de
>> > tus cuellos de botella.
>> Por ello insisto que si modificas la función de postgresql que hace el
>> índice
>> y lo haga con los valores reemplazados mientras se insertan, y que la
>> comparación reemplace en el núcleo de postgresql los valores de búsqueda y
>> por
>> registro no tendrías que llamar a una función que te aseguro que por ser
>> un
>> procedimiento embebido debe hacer más de 3 function calls por registro.
>>
>> :p
>> > Saludos
>> >
>> > El día 4 de abril de 2011 16:50, Gustavo Guillermo Perez
>> >
>> > <gustavo en compunauta.com> escribió:
>> > > El Lunes 04 Abril 2011, Ixcoatl Perez escribió:
>> > >> Esta opcion:
>> > >>
>> > >> CREATE OR REPLACE FUNCTION asciify(unicode text) RETURNS text AS $$
>> > >> DECLARE
>> > >>     translated text;
>> > >> BEGIN
>> > >>     translated := '';
>> > >>     FOR i in 1..(char_length(unicode)) LOOP
>> > >>         translated := translated ||
>> > >> chr(ascii(substring(unicode,i,1))%128); END LOOP;
>> > >>     RETURN translated;
>> > >> END;
>> > >> $$ LANGUAGE plpgsql;
>> > >>
>> > >> No es mala porque en realidad el codigo no se interpreta cada vez que
>> > >> se hace la comparacion. Cuando creas la funcion se compila y se
>> > >> guarda
>> > >> en codigo objeto (o posiblemente maquina), haciendo que su ejecucion
>> > >> sea tan rapida como las funciones nativas.
>> > >
>> > > Si se ejecuta por cada comparación, ya que si tienes almacenado algo
>> > > con
>> > > acento en una tabla y usan o no usan acentos en tu búsqueda estás
>> > > forzado
>> > > a pasar la función por cada registro para sustituir los caracteres
>> > > especiales antes de comparar.
>> > >
>> > >> No la haz probado?
>> > >>
>> > >> Saludos!
>> > >>
>> > >>
>> > >> El día 4 de abril de 2011 16:42, Gustavo Guillermo Perez
>> > >>
>> > >> <gustavo en compunauta.com> escribió:
>> > >> > El Lunes 04 Abril 2011, escribió:
>> > >> >> Que tal Gustavo,
>> > >> >>
>> > >> >> Nuestro problema es que usamos realmente muchos constraints en las
>> > >> >> tablas, y MySQL simplemente se arrana cual vaca en medio de la
>> > >> >> carretera con estas características.
>> > >> >>
>> > >> >> Por ejemplo, acabo de implementar la función:
>> > >> >>
>> > >> >> CREATE OR REPLACE FUNCTION sp_ascii(character varying)
>> > >> >> RETURNS text AS
>> > >> >> $BODY$
>> > >> >> SELECT TRANSLATE
>> > >> >> ($1,
>> > >> >> 'áàâãäéèêëíìïóòôõöúùûüÁÀÂÃÄÉÈÊËÍÌÏÓÒÔÕÖÚÙÛÜçÇ',
>> > >> >> 'aaaaaeeeeiiiooooouuuuAAAAAEEEEIIIOOOOOUUUUcC');
>> > >> >> $BODY$
>> > >> >> LANGUAGE 'sql' IMMUTABLE;
>> > >> >>
>> > >> >> La cual sustituye todo caracter acentuado, tanto en la cadena de
>> > >> >> búsquda como en el campo en el cual se realiza la misma.
>> > >> >> Posteriormente, creando el índice (que termina en más de 10
>> > >> >> minutos
>> > >> >> porque la tabla tiene casi 12 millones de registros):
>> > >> >>
>> > >> >> CREATE INDEX ksp_ascii_lastname ON clients
>> > >> >> (lower(sp_ascii(lastname)));
>> > >> >>
>> > >> >> Para aventarle el query:
>> > >> >>
>> > >> >> SELECT * FROM clients WHERE lower(sp_ascii(lastname)) LIKE
>> > >> >> lower(sp_ascii('pérez'));
>> > >> >>
>> > >> >> Que me responde (en casi dos minutos):
>> > >> >>
>> > >> >> '47168 rows found'
>> > >> >>
>> > >> >> .... Esto no suena a una respuesta profesional aceptable. Pero
>> > >> >> tengo
>> > >> >> la esperanza de poder hacer un tuning a Postgres.
>> > >> >>
>> > >> >> Algun tip al respecto?. Saludos.-
>> > >> >
>> > >> > Claro que sí, es opensource, puedes modificar el código fuente en C
>> > >> > para que te transforme las comparaciones, por una función tuya que
>> > >> > sustituya la de simplemente ==, eso te daría muchísima velocidad y
>> > >> > podrías ponerlo como una opción en postgresql a la hora de
>> > >> > construirlo y hacer público el parche.!!! esa es la idea de que
>> > >> > postgresql y mysql son opensource, que puedes modificarlos.!!!!
>> > >> >
>> > >> > Respecto a los constraints, MySQL tiene varios drivers internos de
>> > >> > almacenamiento y no todos lo soportan es cierto eso no quiere decir
>> > >> > que no tenga soporte, al crear las tablas uno elije que tipo de
>> > >> > storage, sabiendo pro/cons puedes elegir entre
>> > >> > velocidad/journaling/constraints etc.
>> > >> >
>> > >> > para hacer esto te recomendaría buscar una biblioteca común de utf8
>> > >> > para que conviertas las cadenas a utf8, luego las pases a
>> > >> > minúsculas
>> > >> > a ambas y por último antes de hacer la comparación, reemplazar
>> > >> > íÍïÏì
>> > >> > por i antes de ejecutar ==.
>> > >> > También deberías modificar las funciones que actualizan y modifican
>> > >> > el
>> > >> > índice para indexar las versiones minúsculas y con los caracteres
>> > >> > convertidos, siendo que no vas a alterar el registro original, solo
>> > >> > la
>> > >> > versión del char con el que indexas y comparas.
>> > >> >
>> > >> > Saludos.
>> > >> >
>> > >> >> > From: gustavo en compunauta.com
>> > >> >> > To: ayuda-linux en googlegroups.com
>> > >> >> > Subject: Re: [AYUDA] Queries de caracteres acentuados en
>> > >> >> > Postgres
>> > >> >> > Date: Mon, 4 Apr 2011 15:50:42 -0500
>> > >> >> >
>> > >> >> > El Lunes 04 Abril 2011, escribió:
>> > >> >> > > Que tal estimadísimos,
>> > >> >> > >
>> > >> >> > > Mi duda con Postgres 8.4, es cómo diablos puedo ejecutar un
>> > >> >> > > select, donde un campo (p.e: nombre) conincida con 'maría' y
>> > >> >> > > me
>> > >> >> > > arroje los resultados:
>> > >> >> > >
>> > >> >> > > MARIA
>> > >> >> > > MARÍA
>> > >> >> > > maria
>> > >> >> > > maría
>> > >> >> >
>> > >> >> > tal vez con SIMILAR TO.
>> > >> >> >
>> > >> >> > > Alguien ya resolvió esto en postgres?
>> > >> >> >
>> > >> >> > Te recomiendo que si tu proyecto es nuevo lo analices, alomejor
>> > >> >> > no
>> > >> >> > te conviene utilizar postgresql sino MySQL, no estoy a favor de
>> > >> >> > uno o del otro, sino que mysql en tu caso encuentra con 'maria'
>> > >> >> > todos tus casos como los listaste.
>> > >> >> >
>> > >> >> > Saludos.
>> > >> >> >
>> > >> >> > > Saludos y gracias de antemano.
>> > >> >
>> > >> > --
>> > >> > Gustavo Guillermo Perez
>> > >> > http://www.compunauta.com
>> > >> > http://www.compunauta.net
>> > >> > http://anuncios.compunauta.net
>> > >> >
>> > >> > --
>> > >> > Has recibido este mensaje porque estás suscrito a Grupo
>> > >> > "ayuda-linux"
>> > >> > de Grupos de Google.
>> > >> > Si quieres publicar en este grupo, envía un mensaje de correo
>> > >> > electrónico a ayuda-linux en googlegroups.com
>> > >> > Para anular la suscripción a este grupo, envía un mensaje a
>> > >> > ayuda-linux-unsubscribe en googlegroups.com
>> > >> > Para obtener más opciones, visita este grupo en
>> > >> > http://groups.google.es/group/ayuda-linux?hl=es. o
>> > >> > http://www.compunauta.com/ayuda/
>> > >
>> > > --
>> > > Gustavo Guillermo Perez
>> > > http://www.compunauta.com
>> > > http://www.sendadevida.org
>> > > http://anuncios.compunauta.net
>> > >
>> > > --
>> > > Has recibido este mensaje porque estás suscrito a Grupo "ayuda-linux"
>> > > de Grupos de Google.
>> > > Si quieres publicar en este grupo, envía un mensaje de correo
>> > > electrónico a ayuda-linux en googlegroups.com
>> > > Para anular la suscripción a este grupo, envía un mensaje a
>> > > ayuda-linux-unsubscribe en googlegroups.com
>> > > Para obtener más opciones, visita este grupo en
>> > > http://groups.google.es/group/ayuda-linux?hl=es. o
>> > > http://www.compunauta.com/ayuda/
>>
>>
>> --
>> Gustavo Guillermo Perez
>> http://www.compunauta.com
>> http://www.sendadevida.org
>> http://anuncios.compunauta.net
>>
>> --
>> Has recibido este mensaje porque estás suscrito a Grupo "ayuda-linux"
>> de Grupos de Google.
>> Si quieres publicar en este grupo, envía un mensaje de correo
>> electrónico a ayuda-linux en googlegroups.com
>> Para anular la suscripción a este grupo, envía un mensaje a
>> ayuda-linux-unsubscribe en googlegroups.com
>> Para obtener más opciones, visita este grupo en
>> http://groups.google.es/group/ayuda-linux?hl=es. o
>> http://www.compunauta.com/ayuda/
>>
>> --
>> Has recibido este mensaje porque estás suscrito a Grupo "ayuda-linux"
>> de Grupos de Google.
>> Si quieres publicar en este grupo, envía un mensaje de correo
>> electrónico a ayuda-linux en googlegroups.com
>> Para anular la suscripción a este grupo, envía un mensaje a
>> ayuda-linux-unsubscribe en googlegroups.com
>> Para obtener más opciones, visita este grupo en
>> http://groups.google.es/group/ayuda-linux?hl=es. o
>> http://www.compunauta.com/ayuda/
>>
>> --
>> Has recibido este mensaje porque estás suscrito a Grupo "ayuda-linux"
>> de Grupos de Google.
>> Si quieres publicar en este grupo, envía un mensaje de correo
>> electrónico a ayuda-linux en googlegroups.com
>> Para anular la suscripción a este grupo, envía un mensaje a
>> ayuda-linux-unsubscribe en googlegroups.com
>> Para obtener más opciones, visita este grupo en
>> http://groups.google.es/group/ayuda-linux?hl=es. o
>> http://www.compunauta.com/ayuda/
>
> --
> Has recibido este mensaje porque estás suscrito a Grupo "ayuda-linux"
> de Grupos de Google.
> Si quieres publicar en este grupo, envía un mensaje de correo
> electrónico a ayuda-linux en googlegroups.com
> Para anular la suscripción a este grupo, envía un mensaje a
> ayuda-linux-unsubscribe en googlegroups.com
> Para obtener más opciones, visita este grupo en
> http://groups.google.es/group/ayuda-linux?hl=es. o
> http://www.compunauta.com/ayuda/

-- 
Has recibido este mensaje porque estás suscrito a Grupo "ayuda-linux"
de Grupos de Google.
Si quieres publicar en este grupo, envía un mensaje de correo
electrónico a ayuda-linux en googlegroups.com
Para anular la suscripción a este grupo, envía un mensaje a
ayuda-linux-unsubscribe en googlegroups.com
Para obtener más opciones, visita este grupo en
http://groups.google.es/group/ayuda-linux?hl=es. o http://www.compunauta.com/ayuda/



Más información sobre la lista de distribución Ayuda