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 ;-)
-
Enviado a la lista de correo pgsql-es-ayuda ([email protected])
Para cambiar tu suscripci�n:
http://www.postgresql.org/mailpref/pgsql-es-ayuda