[spip-dev] Hash MD5 dans l'indexation...

Hello,

La réponse est sans doute aussi conne que la question que je me pose :

À quoi servent les 64 premiers bits du hash MD5 lors de l'indexation ?

En effet, lors de la recherche, la clause WHERE est du type "dico LIKE 'mot%'"
Donc ça ne sert pas à la recherche.

Pour les jointures, un tout bête ID en bigint serait aussi efficace et moins
coûteux à générer.

donc... ben ya un truc qui doit m'échapper là ...

Salut,

La réponse est sans doute aussi conne que la question que je me pose :

À quoi servent les 64 premiers bits du hash MD5 lors de l'indexation ?

A accélérer l'indexation.

Avec un id autoincrémenté par MySQL : pour chaque mot d'un texte indexé,
il faut faire un SELECT sur le dico, et attendre le résultat du SELECT
pour balancer le INSERT sur la table d'index. S'il y a 500 mots distincts,
ça fait 500 SELECT (et, à un plus bas niveau, 1000 changements de contexte
probablement), c'est pas génial.

Avec un hash calculé en PHP : tous les mots d'un texte indexé peuvent
être insérés en une seule fois dans la table d'index, sans faire de lookup
dans le dico. Il reste deux requêtes SQL, certes grosses : un INSERT
pour la table d'index et un autre sur le dico. Le deuxième est même
un INSERT DELAYED afin de ne pas attendre la complétion de la requête.

Le but est que l'indexation soit absolument insensible : sur un serveur
mutualisé "normal", elle ne doit pas prendre plus d'une seconde, y compris
pour un gros texte (plus de 40 ko). A comparer avec PHPDig, qui prend plusieurs
dizaines de seconde par page.

Le seul inconvénient est que là où on aurait pu se contenter d'un id
sur 32 bits, le hash doit faire 64 bits pour éviter toute collision
(j'aurais pu aussi essayer de bidouiller pour le limiter à 48 bits ;-)).
Donc les tables sont sensiblement plus volumineuses.

Autrement, pour tes améliorations sur la regexp, je vais regarder ça,
mais effectivement la mienne était assez faillible !

a+

Antoine.

Salut,

> La réponse est sans doute aussi conne que la question que je me pose :
>
> À quoi servent les 64 premiers bits du hash MD5 lors de l'indexation ?

A accélérer l'indexation.

Avec un id autoincrémenté par MySQL : pour chaque mot d'un texte indexé,
il faut faire un SELECT sur le dico, et attendre le résultat du SELECT

Ok, je comprends mieux le souci. Dommage qu'il n'y ait pas les procédures
stockées sous MySQL...

Autrement, pour tes améliorations sur la regexp, je vais regarder ça,
mais effectivement la mienne était assez faillible !

Je sais pas quelle version t'as récupérée. La première qui est restée qques
heures sur LF.NET ne marchait pas avec un SPIP "appellation d'origine
contrôlée". En fait l'indexation marchait, mais pas la recherche parce que
nettoyer_chaine() retournait des '+' à la place d'espaces comme séparateurs
(j'ai l'habitude d'utiliser les '+', c'est plus lisible au débugging.
L'espace on sait jamais combien il y en a, et si ce sont de vrais espaces ou
bien des caractères non imprimables).

Ensuite, il y eu a une seconde version, qui marchait bien, mais qui
n'enlevait pas les antiquotes (`). Le SPIP "appellation d'origine contrôlée"
ne le faisait pas non plus d'ailleurs.
La version actuelle marche parfaitement bien. Le dico de LinuxFrench.net
contient plus de 15 000 mots, sans mots 'parasite'. Il y a encore quelques
cas où j'hésite sur l'attitude à adopter :

- les '-' qui sont en miliieux de mots. Pour l'instant je les garde.
- Les chiffres. Pour l'instant je les considère comme des caratères normaux.
Ca permet de faire des recherches du type 'janvier 2002'. Mais du coup il y a
dans le dico des choses du genre "0-test10-pre10" ou "14284416". Alors je me
demande si je vais pas sucrer les "mots" uniquement composés de plus de 5
chiffres. Je pensais aussi à sucrer les chiffres en débuts de mots mais ça
ferait perdre des choses pouvant être intéressantes comme "1280x960" ou bien
"12h30" et "2eme".
- Le @ (je le garde).
- Le "_" (je le garde aussi).

Enfin ça ne concerne que 250 mots sur un dico de :(15284 total) mots.

Pour terminer, j'ai mis en place sur linuxfrench un système de "deadwords"
(mots à ne pas indexer). Ça marche aussi très bien, ça évite de surcharger
les index inutilement. Cependant, je ne propose pas (encore) cette mise à
jour à cause d'un problème tout bête : inc_index pouvant être appelé depuis
l'espace public comme l'espace privé, je ne peux pas faire de
include("deadwords.php3"); en chemin relatif, mais en chemin absolu :
include("/html/ecrire/deadwords.php3");

Ma connaissance du PHP étant encore assez limitée, il me faut le temps de
trouver l'astuce :slight_smile:

Je travaille aussi sur une gestion d'acronymes (mots à indexer tels quels,
quelque soit leur longueur). Par ex : FBI, CIA, CGT, SQL, KDE ...

Et également sur une gestion de suffixe. Le dico n'enregistrerait qu'une
seule entrée pour "heureux, heureuse etc.". Et une recherche sur "heureux"
sortirait les articles avec "heureuses"

Pour info, voila à quoi ressemble le fichier "deadwords" :

$deadwords = array( "conjonction"=>"(mais)|(donc)|(aussi)|(parce)",
"etre"=>"(etre)|(suis)|(sommes)|(etes)|(sont)|(etais)|(etait)|(etions)|(etiez)|(etaient)|(serais)|(seras)|(sera)|(seriez)|(serions)|(seront)|(soit)",
"avoir"=>"(avoir)|(aura)|(auras)|(aurais)|(aurait)|(auront)|(aurions)|(avez)|(avons)|(aviez)|(avaient)|(auraient)",
"aller"=>"(aller)|(allons)|(allez)|(vont)",
"faire"=>"(faire)|(fait)|(faite)|(faites)|(fais)|(faits)",
"pronom"=>"(nous)|(vous)|(elle)|(elles)|(tout)|(tous)|(toute)|(toutes)|(quel)|(quelle)|(quels)|(quelles)|(quoi)|(ceci)|(cela)",
"preposition"=>"(avec)|(sans)|(sous)|(vers)|(alors)|(avant)|(apres)|(pour)|(plus)|(moins)|(dans)|(bien)|(ainsi)|(encore)|(meme)|(tres)",
"demonstratif"=>"(cette)|(cela)|(celle)|(celles)|(ceux)",
"code"=>"(http)|(href)",
"adv"=>"(tant)|(lors)|(trop)|(assez)|(presque)|(presqu)|(puis)",
"adj_possessifs"=>"(notre)|(votre)|(leur)|(leurs)"
);