From: | Gunnar Wolf <gwolf(at)gwolf(dot)org> |
---|---|
To: | José Manuel Ruiz <josemanuelruizbaena(at)gmail(dot)com> |
Cc: | pgsql-es-ayuda(at)postgresql(dot)org |
Subject: | Re: Búsqueda de palabras con Acentos |
Date: | 2010-09-23 18:56:10 |
Message-ID: | 20100923185610.GH23660@gwolf.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-es-ayuda |
José Manuel Ruiz dijo [Tue, Sep 21, 2010 at 05:59:59PM +0200]:
> Buenas.
>
> Tengo un problema con una base de datos PostgreSQL con codificación UNICODE
> que da soporte a una aplicación en PHP.
>
> Todo funcionaba correctamente hasta que me pidieron que una búsqueda de por
> ejemplo "Martin" debería devolver los registros "Martin" y también los
> "Martín".
>
> ¿Cómo puedo solucionar esto? Ya utilizo ilike en lugar de like para que no
> distinta entre "Martin" y "martin".
>
> No me preocupaba hasta que me dí cuenta de que MySQL con codificación
> utf8_general lo hace sin problemas. ¿Hay alguna solución para esto?
Ummm... Creo que -en líneas generales- estás buscando una solución
demasiado angosta ;-)
Si vas a hacer búsquedas sobre texto completo, y si quieres que además
estas búsquedas identifiquen palabras relacionadas (como Martin por
Martín, o como "educativo" por "educar"), puedes hacer tus búsquedas
usando TSearch2. Esto implica que manejes un trigger al crear o
modificar tus datos. Pero las ganancias bien valen la pena:
Carga primero las definiciones de tsearch2 - en mi caso (Debian, para
la DB 'test'):
$ psql test < /usr/share/postgresql/9.0/contrib/tsearch2.sql
Y ya desde psql
test=# select set_curcfg('spanish');
set_curcfg
------------
(1 row)
test=# CREATE TABLE blah (id serial, datos text, datos_vect tsvector);
NOTICE: CREATE TABLE will create implicit sequence "blah_id_seq" for
serial column "blah.id"
CREATE TABLE
test=# CREATE INDEX blah_idx ON blah USING gist(datos_vect);
CREATE INDEX
test=# CREATE TRIGGER vect_update BEFORE UPDATE OR INSERT ON blah FOR
EACH ROW EXECUTE PROCEDURE tsearch2(datos_vect, datos);
CREATE TRIGGER
Le aventamos algunos datos:
test=# INSERT INTO blah (datos) VALUES ('Martín martillaba educativos educadamente');
INSERT 0 1
test=# INSERT INTO blah (datos) VALUES ('¿Qué es lo que dices que Martin Martillaba?');
INSERT 0 1
test=# INSERT INTO blah (datos) VALUES ('Claramente he dicho que Martín martillaba educativos educadamente');
INSERT 0 1
test=# INSERT INTO blah (datos) VALUES ('Tu enunciado carece de educación. O por lo menos, carece de consistencia interna. Es incomprensible.');
INSERT 0 1
test=# INSERT INTO blah (datos) VALUES ('Entonces no hablamos de Martin, sino que de mi!');
INSERT 0 1
Y hacemos una consulta simple (con la sintaxis adecuada para
TSearch2):
test=# SELECT id, datos from blah where datos_vect @@ to_tsquery('Martín');
id | datos
----+-------------------------------------------------------------------
1 | Martín martillaba educativos educadamente
2 | ¿Qué es lo que dices que Martin Martillaba?
3 | Claramente he dicho que Martín martillaba educativos educadamente
5 | Entonces no hablamos de Martín, sino que de mi!
(4 rows)
id | datos
----+------------------------------------------------------------------------------------------------------
1 | Martín martillaba educativos educadamente
3 | Claramente he dicho que Martín martillaba educativos educadamente
4 | Tu enunciado carece de educación. O por lo menos, carece de consistencia interna. Es incomprensible.
(3 rows)
Bueno, y basta de trucos de mago. ¿Cómo ocurre esto en verdad? Veamos
qué es lo que en realidad estoy preguntando:
test=# select to_tsquery('Educar'), to_tsquery('Martín');
to_tsquery | to_tsquery
------------+------------
'educ' | 'martin'
(1 row)
¿Y cómo están guardados los datos para responder a esta solicitud?
test=# select datos_vect from blah;
datos_vect
--------------------------------------------------------------------------------------
'educ':3,4 'martill':2 'martin':1
'dic':5 'martill':8 'martin':7
'clar':1 'dich':3 'educ':7,8 'martill':6 'martin':5
'carec':3,10 'consistent':12 'educ':5 'enunci':2 'incomprens':15 'intern':13 'men':9
'entonc':1 'habl':3 'martin':5 'sin':6
(5 rows)
Espero que te sea más útil que simplemente botar acentos ;-)
From | Date | Subject | |
---|---|---|---|
Next Message | Carlos Bazán | 2010-09-23 19:12:27 | Re: Migracion de 8.4 a 9 (problemas con libperl.so) |
Previous Message | Jaime Casanova | 2010-09-23 18:25:43 | Re: Migracion de 8.4 a 9 (problemas con libperl.so) |