web-dev-qa-db-fra.com

Postgres Texte complet Recherche avec non-Accent et inflexion (conjugation, etc.)

Je veux pouvoir rechercher des phrases non accentuées dans une langue infligée (polonaise) à Postgres.

Dire, si un document contient robiłem, le lexeme devrait être robić (l'infinivite). Ses formes sont robię, robił, robiła etc. Je veux être capable de le trouver, par exemple, avec une phrase robie qui est non accentré robię.

ce que j'ai fait est-ce que j'ai commencé avec une recherche de texte de texte polonais de travail parfaitement

CREATE TEXT SEARCH DICTIONARY polish_ispell (
TEMPLATE = pg_catalog.ispell,
dictfile = 'polish', afffile = 'polish', stopwords = 'polish' );

Ensuite, j'ai essayé de l'étendre pour inclure le unaccent.

create extension unaccent;
create text search configuration polish_unaccented (copy = polish);
ALTER TEXT SEARCH CONFIGURATION polish_unaccented   ALTER MAPPING FOR hword, 
hword_part, Word WITH unaccen, polish_ispell, simple, ;

Malheureusement, les Lexems ne sont pas créés correctement avec cette configuration:

select to_tsvector('polish_unaccented' ,'robił');

'robil':1

Le Lexem devrait être bien sûr:

'robić':1

Donc, le dessous ne peut pas retourner vrai (et c'est ce dont j'ai besoin, je pense):

select to_tsvector('polish_unaccented','robić') @@ to_tsquery('polish_unaccented','robie');

J'ai googlé mais n'a trouvé aucun document montrant comment configurer vraiment Postgres pour mon cas. Les documents ne montrent que l'exemple boiteux 'Hôtels', qui n'est pas un mot "lexemé".

Acclamations

4
Tomek

AFAIK, vous ne pouvez pas faire ce que vous voulez avec les configurations de texte completsql actuelles (dictionnaires et analyseurs/lexers/lexers), bien que certains Solution de contournement Pourrait faire quelque chose près de l'astuce.

Je ne connais pas la polonaise, mais j'ai eu des problèmes similaires avec l'espagnol (qui a également des conjugaisons, etc.), et avec le fait que les gens ont complètement accueilli au fait que Google est capable d'ignorer les accents et ils les ignorent simplement aussi bien.

Dictionnaires

Vous pouvez avoir plusieurs dictionnaires pour PostgreSQL , qui peuvent faire différentes choses, mais simplifier essentiellement vos textes. Ce que vous voulez faire si vous voulez convertir des mots à ses lexemes consiste à utiliser un Dictionnaire ISPell :

[...] qui peut normaliser de nombreuses formes linguistiques différentes d'un mot dans le même lexeme. Par exemple, un dictionnaire anglais ISPELL peut correspondre à toutes les déclasses et conjugations de la Banque de la Banque, des banques, des banques, des banques et des banques.

Cependant, ce dictionnaire (au moins en espagnol) ne reconnaîtra que des mots correctement accentués, ou il ne sera pas capable de savoir à quels lexeme Un certain mot (éventuellement accentué) correspond à. En effet, les entrées dans les dictionnaires ISPELL , telles que le Polonais ISPell Dictionary sont écrites avec tous les accents appropriés (ou des diacritiques) [comme cela devrait].

Le dictionnaire Ispell Polsih est composé de deux fichiers, l'un appelé pl_PL.dic (codé en tant que ISO-8859-2, autant que j'ai été capable de devinez) et une appelée pl_PL.aff. Le premier contient des règles Lexemes + qui s'appliquent à eux, la seconde contient les significations de ces règles. Le logiciel ISPELL interprète ces fichiers pour déterminer comment transformer les mots en lexemes [ainsi que comment vérifier si une orthographe est correcte ou non].

Les entrées sur le .dic Le fichier ressemble à:

abecadło/UV
abecadłowy/bxXyY
[...]
Abisyńczyk/NOqsT
abisyński/XxYbyc

Le .aff fichier donne des règles pour la signification du "U" et "V" et de toutes les autres lettres que de suivre le / signer. Certains si ces règles (que je suis loin de savoir) deviendront le logiciel Comment suffixe ou préfixes Travail pour le mot Abecadło. Par exemple:

SFX U   ło        le        [^astz]ło

Comme il n'y a pas de mot comme abecadlo ou abisynski dans ce dictionnaire, si vous entrez ces textes dans votre recherche, le dictionnaire ne renvoie aucun lexeme.

Solution possible : manipuler le fichier de dictionnaire et dupliquer toutes les lignes avec des caractères accentués avec l'équivalent non accenté. Vous auriez probablement besoin de faire quelque chose de similaire avec le .aff une partie du dictionnaire.

Probablement, vous auriez également besoin d'utiliser un Dictionnaire de synonyme pour rendre les versions accentuées et non accentuées de tous les mots ont la même signification.

Ceci est une approche de la force brute et, dans la pratique, vous inventiriez une "nouvelle version de la langue polonaise, où les lettres accentuées sont équivalentes à leurs homologues non accentués". [Ne dites pas aux fabricants de dictionnaires qui leur ont fait s'assurer que les gens seraient Sort correctement ;-)].

Je pense que cette approche a de très nombreux risques . Je sais que je ne le ferais pas en espagnol ou en catalan, car la présence ou l'absence d'une marque diacritique peut changer radicalement la signification d'un mot ("Año" n'a pas grand-chose à voir avec "ano", en espagnol; et la considération de la synonyme est extrêmement délicate).

Vous devrez évaluer si cela s'applique à la polonaise ou non.


alternative : Vous pouvez simplement utiliser une combinaison d'un Dictionnaire simple et le filtrage " "- unnacent module . Vous n'obtiendrez pas les lexemes et les transformations que cette combinaison est capable de faire ne sont pas si sophistiquées ... mais vous obtiendrez le même résultat lorsque vous recherchez Abecadło ou Abecadlo.

Dans mon cas, j'ai fini par règlement pour cette solution.


Deuxième alternative : Si vous avez besoin d'une recherche de texte qui a la capacité d'ignorer les accents, de permettre aux petites fautes mal orthographiques et de posséder de nombreuses possibilités sophistiquées, envisagez d'utiliser un Solution Sortie de la base de données, telle que Apache Solr . C'est évidemment une approche très différente et vous avez besoin d'un processus pour le rendre synchronisé avec la base de données.

1
joanolo

Wow, c'était amusant. J'ai donc écrit un programme pour faire cela pour vous appelé pg_hunspell

pg_hunspell pl PL polish

SELECT to_tsvector('polish' ,'robił');
 to_tsvector 
-------------
 'robić':1
(1 row)
1
Evan Carroll