[spip-dev] FULLTEXT : commentaire sur dernière modification

Bonjour à tous,

J’ai remarqué la dernière modification apportée au plugin FULLTEXT :
=> http://zone.spip.org/trac/spip-zone/changeset/45288/plugins/fulltext

C’est une simple vérification au niveau de la longueur de la saisie. Curieusement, c’est une regexp qui est utilisée, et pas un simple mb_strlen().
Comme c’est fait actuellement, mon site bilingue fr/chinois ne permet pas une recherche en chinois sur 1, 2 ni même sur 3 caractères…

Quelqu’un peut m’expliquer le pourquoi ce cette regexp ? Que veut-on éviter exactement en procédant ainsi ?
Ne peut-on pas remplacer ce traitement par un simple check sur la longueur de la saisie ? ( mb_strlen($recherche) <=3 )
Ça permettrait à mon formulaire de recherche de fonctionner enfin correctement dans les deux langues… :confused:

Merci !
Med.

J’ai remarqué la dernière modification apportée au plugin FULLTEXT :
=> http://zone.spip.org/trac/spip-zone/changeset/45288/plugins/fulltext

C’est une simple vérification au niveau de la longueur de la saisie. Curieusement, c’est une regexp qui est utilisée, et pas un simple mb_strlen().

oui car on en vérifie aussi le contenu avec \w

Comme c’est fait actuellement, mon site bilingue fr/chinois ne permet pas une recherche en chinois sur 1, 2 ni même sur 3 caractères…

je ne comprends pas, car si tu entres 3 caractères chinois, cette ligne ne devrait rien faire. Peux-tu donner un exemple de recherche qui fonctionne sans cette ligne, et ne marche plus avec ?

Quelqu’un peut m’expliquer le pourquoi ce cette regexp ? Que veut-on éviter exactement en procédant ainsi ?

Actuellement les mots de trois lettres (ONU, OMS, CPU, RAM…) ne sont pas cherchables par fulltext ; je remplace donc par ONU* OMS* etc, qui donnent des résultats. Bien sûr il ne faut pas que ça affecte une recherche en chinois…

– Fil

Merci pour ta réponse.

Mon problème ne se situe à vrai dire pas sur cet ajout en particulier, il concerne le plugin fulltext tout court.
C’est simplement qu’en regardant le code, j’ai vu cet ajout et j’ai tiqué justement sur le fait qu’une des raisons pour laquelle les recherches en chinois déconnent sur mon site (a priori, sauf si bien sûr je fais fausse route), c’est la gestion des “petits” mots.

En chinois, une recherche sur des “mots” de 1, 2 ou 3 caractères devrait être autorisée, puisque la notion de nombre de caractères ne s’applique pas dans cette langue comme elle s’applique en français par exemple. Ainsi, rechercher des combinaisons de 1, 2 ou 3 caractères chinois devrait être permis, mais a priori ça ne l’est pas actuellement (ou alors j’ai loupé quelque chose).

Du coup, j’aimerais bien que cet ajout, en plus d’ajouter le caractère étoile aux petits mots français, l’ajoute également aux petits mots chinois. D’où ma question sur le pourquoi de la regexp, et la possibilité ou pas de la remplacer par un simple test sur la longueur de la chaîne.

Il faudra de toute manière que je procède autrement, probablement en déterminant la présence ou pas de caractères non ascii dans la chaîne, pour que la recherche soit efficace totalement. Mais commencer par autoriser les mots courts serait un premier pas.

Med.

Mon problème ne se situe à vrai dire pas sur cet ajout en particulier, il concerne le plugin fulltext tout court.

ah ! d'où ma perplexité :slight_smile:

En chinois, une recherche sur des "mots" de 1, 2 ou 3 caractères devrait être autorisée, puisque la notion de nombre de caractères ne s'applique pas dans cette langue comme elle s'applique en français par exemple. Ainsi, rechercher des combinaisons de 1, 2 ou 3 caractères chinois devrait être permis, mais a priori ça ne l'est pas actuellement (ou alors j'ai loupé quelque chose).

en fait le plugin Fulltext n'"interdit" rien de lui même, il se
contente de passer la requête à l'indexation FULLTEXT de MySQL. Or par
défaut celle-ci est prévue pour n'indexer que les mots de 4 lettres ou
plus. L'ajout d'une étoile est un contournement imparfait de cette
limitation.

Du coup, j'aimerais bien que cet ajout, en plus d'ajouter le caractère étoile aux petits mots français, l'ajoute également aux petits mots chinois. D'où ma question sur le pourquoi de la regexp, et la possibilité ou pas de la remplacer par un simple test sur la longueur de la chaîne.

je vois ; mais en l'occurrence il vaut sans doute mieux reconfigurer
ton fulltext pour qu'il indexe tout, comme indiqué dans la doc

(section "Étendre la recherche aux mots de 3 lettres")

-- Fil

Hum… Oui et non.

J’ai bien compris le contournement imparfait, et effectivement mon problème vient en réalité du fonctionnement du fulltext sur MySQL. Mais je souhaite pouvoir chercher jusqu’à un seul cacarctère ici : que se passera-t-il si j’indexe tout jusqu’aux mots de une lettre ? Les perfs vont prendre une grosse claque, la pertinence des résultats également. Non ?

Ensuite, je pense que le fait qu’il n’y ait pas d’espaces en chinois pose un problème.
Sans recherche avec le caractère *, aucun mot chinois n’est trouvé (sauf quelques très rares cas particuliers) puisque du point de vue du programme, il n’y a qu’un mot et un seul entre deux ponctuations dans un article en chinois…

Du coup, d’après moi la solution de contournement côté php semble inévitable.
D’où ma première question concernant l’ajout pour la gestion des mots courts. D’ailleurs, la regex à laquelle je fais référence, elle est là pour vérifier qu’on ne tape pas un truc du genre “a b” (deux lettres séparées par un espace) ? Si non, elle sert à quoi précisément ? (les regex n’ont jamais été mon fort).

Med.

J'ai bien compris le contournement imparfait, et effectivement mon problème
vient en réalité du fonctionnement du fulltext sur MySQL. Mais je souhaite
pouvoir chercher jusqu'à un seul cacarctère ici : que se passera-t-il si
j'indexe tout jusqu'aux mots de une lettre ? Les perfs vont prendre une
grosse claque, la pertinence des résultats également. Non ?

je ne sais pas, je ne suis pas dev mysql :slight_smile: fais des essais…
peut-être faut-il utiliser un indexeur externe ; en ce moment je
travaille avec Sphinx, c'est très bien (pour du français en tous cas)

Ensuite, je pense que le fait qu'il n'y ait pas d'espaces en chinois pose un
problème.
Sans recherche avec le caractère *, aucun mot chinois n'est trouvé (sauf
quelques très rares cas particuliers) puisque du point de vue du programme,
il n'y a qu'un mot et un seul entre deux ponctuations dans un article en
chinois...

Du coup l'indexation fulltext ne verra qu'un seul et unique mot dans
ton article ? Dans ce cas l'étoile ne suffira pas non plus...

D'ailleurs, la regex à laquelle je fais référence, elle est là pour
vérifier qu'on ne tape pas un truc du genre "a b" (deux lettres séparées par
un espace) ? Si non, elle sert à quoi précisément ? (les regex n'ont jamais
été mon fort).

elle sert à n'appliquer l'étoile que dans le cas que j'avais "bien"
identifié comme problématique, pour éviter des cas auxquels je n'avais
pas réfléchi :slight_smile:

-- Fil

Bonjour,

Je ferais une seconde remarque : utilisant SPIP pour un ensemble de documentations internes informatiques,
nous avons tres souvent des recherches à faire sur des abbreeéviations informatiques (ex. VNC / KVM …) :
y a-t-il un moyen de contourner cette vérification/limitation ?

  • accepter les mots tout majuscules sur 3 lettres ?
  • accepter des mots en “acronymes” ex. K.V.M ?
    Je n’ai pas su trouver l’information…
    merci de vos précisions
    Yx

Encore merci pour toutes ces précisions.
Bon, je vais réfléchir à tout cela, et aviser sur la solution la plus adaptée.
Mais le problème venant effectivement de l’indexation fulltext mysql pas du tout prévue pour des langues type asiatiques (c’est marqué dans la doc…), c’est fort probable que je finisse par me pencher sur une solution externe.

Juste pour revenir sur une de tes dernières remarques : l’étoile servirait justement à faire en sorte que si on tape un mot chinois de par exemple 3 caractères, il soit recherché quoi qu’il arrive, même dans une suite de X caractères qui n’est comprise que comme un seul mot (à la manière de “enfan*” qui permet de remonter “enfant, enfants, etc.”. Bon, c’est très limité comme mode de fonctionnement, mais a priori ça serait déjà mieux que rien.

Med.

Juste pour revenir sur une de tes dernières remarques : l'étoile servirait
justement à faire en sorte que si on tape un mot chinois de par exemple 3
caractères, il soit recherché quoi qu'il arrive, même dans une suite de X
caractères qui n'est comprise que comme un seul mot (à la manière de
"enfan*" qui permet de remonter "enfant, enfants, etc.".

oui mais "f*" ne remonte pas "enfants". Je crains que tu n'arrives à
trouver que ce mot en début de phrase… enfin fais des essais

-- Fil

nous avons tres souvent des recherches à faire sur des abbreeéviations
informatiques (ex. VNC / KVM …) :
y a-t-il un moyen de contourner cette vérification/limitation ?

  • accepter les mots tout majuscules sur 3 lettres ?
  • accepter des mots en « acronymes » ex. K.V.M ?

c’est justement le propos de la doc qui recommande de reconfigurer MySQL Fulltext (c’est hors de portée du plugin SPIP) :

Étendre la recherche aux mots de 3 lettres

Par défaut MySQL FULLTEXT indexe les mots de quatre lettres ou plus. Pour étendre la recherche aux mots de 3 lettres ou plus, il faut modifier la config du serveur (/etc/mysql/my.cnf sous Debian), et ajouter les deux éléments suivants :

[mysqld]
ft_min_word_len=3
[myisamchk]
ft_min_word_len=3

Attention après avoir effectué cette manipulation il est impératif de reconstruire tous les index FULLTEXT de toutes les bases de données présentes sur le serveur, cf. http://dev.mysql.com/doc/refman/5.1….
Une méthode en ligne de commande (il faut être root) :

# /etc/init.d/mysql stop
Stopping MySQL database server: mysqld.
# myisamchk --recover /var/lib/mysql*/*MYI
... (quelques secondes ou minutes) ...
# /etc/init.d/mysql start

– Fil

Après investigation de mon côté, il s’avère que ce problème est “international” : énormément de gens se sont posés les mêmes questions que moi, et se les posent encore parfois. Un indexeur couplé à un tokenizer externe semble être la solution, reste à savoir quel solution libre d’utilisation est vraiment efficace.

Si jamais je m’y casse les dents plus de 3 jours, je finirai par utiliser Google ou Baidu en guise de crawler externe sur mon site. Ca me permettra de profiter de leurs énormes tables/dictionnaires, aux performances non discutables.

Med.