Vous n'êtes pas identifié(e).
Pages : 1
Bonjour à tous,
Je souhaiterais savoir si parmi vous il y en auraient qui utilisent tsearch pour effectuer des recherches en texte intégral sur des document en langue française,
Si oui, est-ce qu'ils connaissent des problèmes de pertinence dans les recherches ?
Hors ligne
docs.postgresql.fr l'utilise, avec beaucoup de bonheur.
Guillaume.
Hors ligne
Bonjour,
Je l'utilise aussi et suis globalement très satisfait de ses résultats. Je rencontre néanmoins 2 problèmes:
-la sensibilité "obligatoire" aux accents (problème que l'on retrouve sur docs.postgresql.fr; par exemple, une recherche sur precharger échoue, alors qu'elle aboutit avec précharger)
-la gestion des traits d'union. Il semblerait que T-search ne fonctionne que sur les lettres. En plus, si ma mémoire est bonne, le - est l'opérateur utilisé pour le "sauf". Mais là, docs.postgresql.fr semble avoir trouvé la parade (essai sur "Saint-Pierre" qui fonctionne correctement). Si quelqu'un a une info. sur la façon dont ce cas a été géré, je suis preneur ;-)
Cordialement,
Hors ligne
la sensibilité "obligatoire" aux accents (problème que l'on retrouve sur docs.postgresql.fr; par exemple, une recherche sur precharger échoue, alors qu'elle aboutit avec précharger)
Voir mes billets sur ce sujet :
* http://blog.guillaume.lelarge.info/inde … es-accents
* http://blog.guillaume.lelarge.info/inde … -le-retour
Je ne l'ai pas encore fait sur docs.postgresql.fr mais ça ne saurait tarder.
la gestion des traits d'union. Il semblerait que T-search ne fonctionne que sur les lettres.
L'opérateur utilisé pour l'opération binaire NOT est le point d'exclamation. Pour ce qui est de docs.postgresql.fr, nous appliquons un certain nombre d'expressions rationnelles pour "filtrer" l'entrée de l'utilisateur. Je ne me rappelle pas de tête mais il me semble que nous supprimons simplement le tiret. Ce qui fait que la recherche est équivalente à "Saint & Pierre" dans ce cas.
Guillaume.
Hors ligne
Sur ce point là, il y a la possibilité de créer un index sans accents.
D'abord faire une fonction qui zappe les accents :
CREATE OR REPLACE FUNCTION prepare_lexico( article TEXT) returns TEXT
AS
$$
DECLARE
travail text;
BEGIN
travail:=translate($1,'éèêëàâäùûïîôöç','eeeeaaauuiiooc');
travail:=translate(travail,'ÉÈÊËÀÂÄÙÛÏÎÔÖÇ','eeeeaaauuiiooc');
RETURN travail;
END;
$$
LANGUAGE plpgsql
IMMUTABLE;
Ensuite créer l'index :
create index gg3 on table_recherche using gin(to_tsvector('fris',prepare_lexico(article)));
Et ensuite les recherches se font normalement :
select article from table_recherche where prepare_lexico(article) @@ to_tsquery(prepare_lexico('expression à rechercher'));
J'ai pas vérifié, mais normalement l'index doit bien être utilisé.
Hors ligne
Oui mais le problème qui vient tout de suite après est que l'extrait renvoyé par ts_headline n'aura pas non plus les accents, ce qui est souvent un problème.
Guillaume.
Hors ligne
Oui mais le problème qui vient tout de suite après est que l'extrait renvoyé par ts_headline n'aura pas non plus les accents, ce qui est souvent un problème.
C'est assez facile à contourner comme problème : Tu récupères la position du highlighted text renvoyé, et tu mets en évidence la même position du texte dans le document original.
C'est un peu du bricolage je te l'accorde, mais ça n'est jamais que du bricolage pour de l'affichage. L'essentiel c'est quand même d'avoir des recherches correctes.
Hors ligne
gleu a écrit :Oui mais le problème qui vient tout de suite après est que l'extrait renvoyé par ts_headline n'aura pas non plus les accents, ce qui est souvent un problème.
C'est assez facile à contourner comme problème : Tu récupères la position du highlighted text renvoyé, et tu mets en évidence la même position du texte dans le document original.
C'est un peu du bricolage je te l'accorde, mais ça n'est jamais que du bricolage pour de l'affichage. L'essentiel c'est quand même d'avoir des recherches correctes.
Ce genre de bricolage a l'air de marcher :
CREATE OR REPLACE FUNCTION mise_en_evidence( article TEXT, sans_accent TEXT, headline TEXT) returns TEXT
AS
$$
DECLARE
thead text;
thead_propre text;
thead_accentue text;
sortie text;
debut integer;
balise_debut varchar;
balise_fin varchar;
BEGIN
balise_debut := '<b>';
balise_fin := '</b>';
thead_propre := replace(replace(headline ,balise_fin ,''),balise_debut,'' );
debut := position(thead_propre in sans_accent);
thead_accentue := substring ( article from debut for length ( thead_propre ));
thead=headline;
sortie='';
debut := position(balise_debut in thead);
WHILE (debut > 0) LOOP
sortie := sortie || substring (thead_accentue from 0 for debut ) || balise_debut ;
thead_accentue := substring (thead_accentue from debut for length(thead_accentue));
thead := substring(thead from debut + length(balise_debut) for length(thead));
debut := position(balise_fin in thead);
sortie := sortie || substring (thead_accentue from 0 for debut ) || balise_fin ;
thead_accentue := substring (thead_accentue from debut for length(thead_accentue));
thead := substring(thead from debut + length(balise_fin) for length(thead));
debut := position(balise_debut in thead);
END LOOP;
sortie := sortie || thead_accentue;
RETURN sortie;
END;
$$
LANGUAGE plpgsql ;
herve=# SELECT id, mise_en_evidence(article, prepare_lexico(article),ts_headline(prepare_lexico(article),q)) FROM (SELECT id, article, q from recherche, to_tsquery('defense') q WHERE prepare_lexico(article) @@ q ) AS foo;
id | mise_en_evidence
----+----------------------------------------------------------------------------------------------------------------------------------
1 | <b>défense</b> des droits des étrangers). «Les “charters conjoints”, insistent-elles, sont contraires au principe d'interdiction
(1 ligne)
Hors ligne
Je connaissais ce post sur unaccent; nous en avions parlé dans un précédent thread ;-)
Quant à l'astuce qui consiste à créer l'index sur une version sans accent du texte, c'est ce que je fais actuellement.
Dans la réalité, pour des pages assez lourdes, le post-traitement nécessaire pour obtenir un affichage avec accents est cependant inutilement lourd (il peut y avoir plusieurs occurrences du terme recherché...)
Enfin, en ce qui concerne l'astuce pour gérer les traits d'union, je regrette parfois que l'approche -par ailleurs puissantissime de PostgreSQL- occulte quelques cas pourtant bien pratiques; par exemple:
-la recherche d'une expression, habituellement associée aux guillemets, n'existe pas (à ma connaissance du moins). Si l'on reprend l'astuce utilisée pour faire ressortir Saint-Pierre, on risque aussi de faire ressortir Saint-Marc, Saint-Paul,... D'une manière générale, je n'ai pas trouvé comment faire une recherche exacte. Un exemple; sur docs.postgresql.fr, si je recherche "postgresql version 8.4", je retrouve entre autres "versions de PostgreSQL™ antérieures à la 8.4". Un moteur de recherche reconnaissant les guillemets n'échouerait pas sur ce point
-la recherche étendue est une des forces de Tsearch, mais elle génère parfois un bruit inutile. Il serait confortable que l'on puisse là aussi forcer une recherche exacte. Par exemple, sur docs.postgresql.fr, si je recherche window (afin d'explorer les nouveautés de la version 8.4, bien sûr), il est dommage de trouver parmi les réponses des articles traitant de Windows.
Il se trouve que la plupart de mes besoins traitent de lieux. Tant que le nom du lieu tient en un mot, cela ne pose pas de problèmes, mais dès que l'on a des noms de lieux composés (tous les Saint-XXX, mais aussi les noms avec sur-sous-le-la-... posent beaucoup de problèmes. La plupart des moteurs de recherche (moteurs Web, Google, Bing,... où intégrés à des produits divers), permettent facilement de contourner ce problème, et de trouver les documents souhaités. Je suis frappé par les innovations réelles et pertinentes qu'apporte PostgreSQL à ce niveau (recherche par racine de mot, dictionnaires de synonymes, thésaurus,...) et, dans le même temps, par le fait qu'il n'apporte pas de réponse à certains critères qui me semblent pourtant assez basiques.
Hors ligne
-la recherche d'une expression, habituellement associée aux guillemets, n'existe pas (à ma connaissance du moins). Si l'on reprend l'astuce utilisée pour faire ressortir Saint-Pierre, on risque aussi de faire ressortir Saint-Marc, Saint-Paul,... D'une manière générale, je n'ai pas trouvé comment faire une recherche exacte. Un exemple; sur docs.postgresql.fr, si je recherche "postgresql version 8.4", je retrouve entre autres "versions de PostgreSQL™ antérieures à la 8.4". Un moteur de recherche reconnaissant les guillemets n'échouerait pas sur ce point
J'aurais tendance à suggérer d'ajouter un « where xxx like "%Saint-Pierre%"... »
Si la recherche tsearch produit un result set d'un nombre de ligne raisonnable, ça ne doit pas être bien pénalisant...
Hors ligne
la recherche d'une expression
La 8.5 le permettra.
Et comme dit Hervé, actuellement, il faut ajouter le filtre sur un LIKE. La recherche plein texte permet de trouver le maximum de possibilité très rapidement alors que le LIKE permet de filtrer sur l'expression exacte.
recherche exacte
Au risque de me répéter, 8.5
Quant à la question des lieux, il doit bien exister un « dictionnaire » des lieux, non ? il serait certainement possible d'ajouter ce dictionnaire à FTS. Je viens bien tester l'idée si on me fournit ce dictionnaire.
Guillaume.
Hors ligne
Je chipote, mais le like ne résout pas tout. Si je recherche "window", le like me retournera aussi windows, à moins de bricoler pour faire une recherche du mot non précédé de lettres, et non suivi de lettres (cela peut être <rien>, un espace, un point, une virgule, un trait d'union,...). Bref, l'éventail des possibilités est large, et il est difficile d'être exhaustif.
Mais bon, si cette fonctionnalité sera rajoutée en 8.5, c'est, je suppose, que je ne suis pas le seul à considérer que son absence peut être gênante.
Il me semble que la contrib unaccent, un temps annoncé pour la version 8.4, devrait également accompagner la sortie de la 8.5.
Par rapport à l'utilisation que je fais de Tsearch, il semblerait donc que la 8.5 comblera les quelques lacunes actuelles. Ca va vraiment devenir le moteur de recherche ultime :-))
Vivement la 8.5 (ça va être dur d'être patient)
Hors ligne
Sinon avec une regexp … (non testé sous postgres j'ai pas le temps tout de suite). en perl ça donnerait ça :
=~ /\bmonfiltre\b/
Sous postgres je pense que ça donnerait ça :
~ E'\ymonfiltre\y'
Marc.
Hors ligne
Il me semble que la contrib unaccent, un temps annoncé pour la version 8.4, devrait également accompagner la sortie de la 8.5.
Il est déjà dans le CVS, donc il fera parti de la 8.5.
Guillaume.
Hors ligne
Pages : 1