User:Kevin Lagaisse

From mediawiki.org

--Draft


Réflexions autour de la recherche sous MySQL[edit]

Recherche de caractères accentués impossible[edit]

Un gros défaut sur MediaWiki est la recherche de chaînes de caractères accentués. J'ai cherché partout et je n'ai trouvé que des constats sans autre solution que le passage vers Lucène.

Pour illustrer le problème, une recherche avec le terme "église" ne renvoie que les résultats contenant "église". Jusqu'ici rien de suspect. Sauf que la recherche ne renvoie pas de résultats contenant le terme "eglise". En effet le moteur fonctionne comme si un "é" était différent d'un "e" (ce qui est vrai dans l'absolu).

On pourrait me rétorquer qu'il suffit de bien orthographier les mots pour que cela ne se produise pas, que Mediawiki n'est pas google, sauf qu'il est d'usage d'écrire "E" pour un "é" en majuscule et là le problème devient capital.

Le problème est double avec un terme comme "traçabilité" ("ç" et "é").

Et pourtant cela devrait fonctionner out of the box[edit]

Quand on installe MediaWiki avec les paramètres par défaut, la table search_index est en classement MyIsam latin1_swedish, capable de stocker un bon nombre de caractères européens.

MediaWiki génère des requêtes natives MySQL du type MATCH AGAINST pour les recherches sur des index de type text générés par MySQL.

Ces deux éléments combinés devraient permettre une recherche sur les caractères accentués.

Mais pourquoi cela ne fonctionne-t-il pas ?[edit]

L'idée est la suivante: MediaWiki, avant de demander à MySQL de créer un "text index", convertit manuellement (en calculant) les caractère bizarres (autres qu'ASCII) grâce à une table de conversion UTF8 (réf nécessaire). C'est pour cela que dans la table on voit des caractères en U8xxx. Sauf qu'en réalité, on voit surtout des u8xxx (avec un u en minuscule). En effet, Mediawiki ajoute un strtolower mal placé pour rendre la chose inexploitable (MySQL ne s'en sort pas plus avec le U majuscule)...

Permettre la recherche sur les caractères accentués[edit]

Une solution consiste à étendre la classe de recherche pour y inclure des modifications afin de laisser faire MySQL avec la création de l'index textuel et avec la recherche sans intervention de Mediawiki.

Et ceci de manière plus ou moins propre.

Modifications faites sur la 1.15.4[edit]
  • Modifier SearchUpdate.php ligne 49 dans le répertoire include :
' ', utf8_encode(strtolower( " " . utf8_decode($text) /*$this->mText*/ . " " )) );
  • Dans LanguageFr.php du répertoire languages/classes ajouter une fonction à la classe LanguageFr :
function stripForSearch($term) { 
   return $term;
}
  • Modification de LocalSettings.php ligne 73 dans le répertoire racine
$wgDBmysql5 = false;
  • Mise à jour de l’index depuis le répertoire maintenance :
php rebuiltextindex.php
Modifications faites sur la 1.16.0beta[edit]
  • Modifier LanguageFr.php

Extension de 2 fonctions. La seconde fonction est une version simplifiée de celle de MediaWiki. Elle va être mise à jour pour permettre toutes les fonctionnalités permises par celle qu'elle surcharge (action pour moi plus tard).

function normalizeForSearch( $term) { //does not convert against u8 table to allow french search
		return $term;
	}
	
function lc( $str, $first = false ) { //does not convert against u8 table to allow french search
		return utf8_encode(strtolower(utf8_decode($str)));
	}
  • Créer la classe SearchMySQLFr.php
class SearchMySQLFr extends SearchMySQL {
	/**
	 * Decode characters for MySQL's indexing
	 */
	function normalizeText( $string ) {
		return utf8_decode($string);
	}
// You can add functions for plural search here (see plural search chapter)
}
  • Dans LocalSettings.php
    • modifier la ligne 77 :
      $wgDBmysql5 = false;
      
    • Ajouter:
require_once( "$IP/includes/search/SearchMySQLfr.php" );
$wgSearchType="SearchMySQLfr";
  • Mettre à jour l’index depuis le répertoire maintenance :
php rebuiltextindex.php

Conclusion[edit]

N'étant pas un expert en UTF8, je ne peux affirmer que cela correspond à tous les besoins pour toutes les langues européennes. Cela a néanmoins l'avantage de fonctionner sur différents environnements installés pour le Français.


Recherche de pluriels[edit]

Modifications en 1.15.4[edit]

  • Modifier la classe SearchMySQL.php à la ligne 87
	/**
	 * Perform a full text search query and return a result set.
	 *
	 * @param string $term - Raw search term
	 * @return MySQLSearchResultSet
	 * @access public
	 */
	function searchText( $term ) {
		$resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ) . "*" , true ) ) ); 
		return new MySQLSearchResultSet( $resultSet, $this->searchTerms );
	}

	/**
	 * Perform a title-only search query and return a result set.
	 *
	 * @param string $term - Raw search term
	 * @return MySQLSearchResultSet
	 * @access public
	 */
	function searchTitle( $term ) {
		$resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) );
		return new MySQLSearchResultSet( $resultSet, $this->searchTerms );
	}


Modifications en 1.16.0beta[edit]

  • Créer la classe SearchMySQLFr.php
class SearchMySQLFr extends SearchMySQL {

//previous functions end here

	/**
	 * Perform a full text search query and return a result set.
	 *
	 * @param $term String: raw search term
	 * @return MySQLSearchResultSet
	 */
	function searchText( $term ) {
		return $this->searchInternal( $term . "*", true );
	}

	/**
	 * Perform a title-only search query and return a result set.
	 *
	 * @param $term String: raw search term
	 * @return MySQLSearchResultSet
	 */
	function searchTitle( $term ) {
		return $this->searchInternal( $term, false );
	}
}

Organisation des fonctions dans la 1.16.0beta[edit]

[FR] Ce serait bien que la fonction normalizeText soit dans Language.php plutôt que dans SearchMySQL.php puisque son implémentation dépend très fortement de la langue. On y trouve même des traitements spécifiques pour le Chinois.

[EN] It would be great and helpful if the function normalizeText could be localised in Language.php instead of in SearchMySQL.php as it uses some tricks which depend on the language to "normalise" the text (i.e. there are some hacks for chinese language)