Extension:LuceneSearch/fr

A quoi sert cette extension ?
Elle sert à implémenter un moteur de recherche alternatif, basé sur la librairie Lucene. Points forts :
 * le moteur de recherche et d'indexation peuvent être séparés
 * recherche ignorant les accents, disponible en 12 langues
 * analyse des liens pour classer les résultats par indice de pertinence
 * recherche ciblée sur un espace de nom particulier

Le logiciel est divisé en deux parties. La première est le démon lsearch, qui permet l'indexation du contenu et les recherches, et la partie extension MediaWiki qui est simplement une interface de MediaWiki avec le démon.

Installation de l'extension MediaWiki
Editez le fichier LocalSettings.php pour ajouter le code suivant. wgLuceneHost peut être un array de serveur (dans une installation distribuée).


 * $wgDisableInternalSearch = true;, permet de désactiver le moteur de recherche d'origine (très important, sinon les recherches ne seront pas faite par Lucene),
 * $wgDisableSearchUpdate = true;, permet de désactiver le système d'indexation intégré pour gagner en performance, étant donné qu'il ne sera plus utilisé.

Utilisation des préfixes de recherche
Les recherches peuvent être préfixées d'un espace de nom. Par exemple en entrant dans la boite de recherche : help:images on aura les occurrences du mot "images" dans l'espace de nom "Help". Il existe un préfixe spéciale : all, qui permet au moteur de recherche de chercher dans tous les noms d'espace (par défaut seul l'espace de nom principal est utilisé).

Notez que les espaces ne sont pas autorisés entre l'espace de nom est les deux points.

Pour faire une recherche dans plusieurs espaces de nom, indiquez leur nom séparé par des virgules. ex. help,project:images.

Personnaliser les préfixes d'espaces de nom
Vous pouvez utiliser des préfixes personnalisés qui regroupent plusieurs espaces, éditez MediaWiki:Searchaliases. Voici un exemple : wp|Project all_talk|Talk,User_talk,Image_talk,MediaWiki_talk,Template_talk,Help_talk,Category_talk

La syntaxe est donc : "alias|&lt;liste d'espaces de nom&gt;", avec un alias par ligne. Vous pouvez traduire le mot clé all en éditant la page MediaWiki:searchall et en ajoutant la traduction du mot clé, à raison d'une traduction par ligne (en français, ce serait "tous" par exemple).

Installer le démon LSearch
Requis: Linux, Java 5, Apache Ant 1.6, Rsync (pour une architecture distribuée) Note pour les utilisateurs Windows: TODO... (pour résumé : passez à Linux, c'est déjà plus indiqué pour un serveur...)

Il y a différentes façons d'installer le moteur, tout dépend de la taille de l'infrastructure et du projet.

Installation sur un serveur unique
Dans la plupart des cas, un seul serveur pourra supporter à la fois l'indexation et la recherche. Généralement la recherche est gourmande en mémoire, et en pratique il est conseillé d'avoir au moins la moitié de l'index en mémoire. Si l'index est 2x plus grand que la taille de la mémoire disponible sur votre système, vous aurez probablement de grosse dégradation en terme de performance ; ce sera donc le moment de considéré une installation de type "distribuée".

Généralement, l'index de recherche est 3 à 5 fois plus petit que la taille du dump XML du wiki indéxé.

Pour facilité la maintenance des architectures "distribuées", la configuration est divisée en deux parties : global et local. Dans une installation sur serveur unique vous devrez quand même renseigner ces deux parties :

Configuration locale : Vous pouvez laisser les autres options à leurs valeurs par défaut.
 * 1) Télécharger les sources du 'démon lsearch' (voir dans l'infobox), et uploadez-les sur votre serveur dans le dossier /home/search/ls2/ (c'est un exemple, les chemins seront à adapter si vous utilisez un autre répertoire). Vous devrez aussi récupérer la librairie mwdumper.jar et la mettre dans /home/search/ls2/lib.
 * 2) Créez un répertoire où les indexes seront stockés, dans notre exemple ce sera : /home/search/indexes
 * 3) Editez le fichier lsearch.conf :
 * 4) * MWConfig.global - mettez ici l'URL du fichier de configuration global (voir ci-dessous), ex. file:///home/search/ls2/lsearch-global.conf
 * 5) * MWConfig.lib - mettez ici le chemin local vers le répertoire des librairies, ex. /home/search/ls2/lib
 * 6) * Indexes.path - le chemin de base où les indexes seront stockés, ex. /home/search/indexes
 * 7) * Localization.url - l'url vers les fichiers de localisation de MediaWiki, ex. file:///home/.../w/languages/messages (c'est le chemin vers le répertoire 'messages' de votre wiki)
 * 8) * Logging.logconfig - chemin local vers le fichier de configuration log4j, ex. /home/search/ls2/lsearch.log4j (le dossier SVN contient un exemple du fichier log4j que vous pouvez utiliser, il est appelé : lsearch.log4j-example)

La configuration globale permet au démon d'avoir des informations sur vos bases de données et l'organisation du réseau.

Configuration globale : Vous pouvez laisser les autres options à leurs valeurs par défaut.
 * 1) Editez le fichier lsearch-global.conf :
 * 2) * Ajouter des bases de données (le nom de la base de données est $wgDBname dans MediaWiki) dans la section [Database]. ex. wikidb : (single) (language,fr) - qui déclare que la base wikidb doit être construite en index unique (non distribué) et que le français est le langage par défaut (important pour la gestion des accents en particulier). En plus, vous devriez aussi ajouter la propriété (warmup,100)'. Cela permet à l'index d'être toujours en mémoire, même lorsqu'il est reconstruit.
 * 3) * Déclarez votre nom d'hôte pour wikidb dans les sections [Search-Group] and [Index sections] (Important : n'utilisez pas localhost, mais le nom d'hôte tel qu'il apparait dans la variable d'environnement $HOSTNAME)
 * 4) * Vous pouvez ajouter vos espaces de nom personalisé dans la section [Namespace-Prefix].

Ensuite, compilez LuceneSearch.jar en lançant ant, puis démarré le démon en exécutant ./lsearchd. Vous devez avoir java dans votre PATH.

Créer un index
Pour garder votre index à jour vous devez le mettre à jour. Vous pouvez créer un script ou une tâche cron pour le faire de manière régulière.

Pour créer l'index, vous aurez besoin d'un dump XML de votre wiki (utilisez le script de maintenance dumpBackup.php). Vous devrez modifier le fichier AdminSettings.php dans votre installation de MediaWiki pour pouvoir utiliser ce script. Ensuite utilisez l'outil Importer, pour recréer l'index. Voici un exemple : (vous devrez ajuster le chemin vers votre installation de MediaWiki, etc...) php /home/.../w/maintenance/dumpBackup.php --current --quiet > /home/search/indexes/wiki.xml && java -cp /home/search/ls2/LuceneSearch.jar org.wikimedia.lsearch.importer.Importer -s /home/search/indexes/wiki.xml wikidb

L'outil Importer va importer le dump xml dump et faire un snapshot (option -s). Ce snapshot sera utilisé par le démon lsearch (qui cherche de manière régulière les snapshots). Les indexes du démon lsearch sont stockés dans des répertoires standards. Si /home/search/indexes est la racine de votre index, alors indexes/snapshot contiendra les snapshots, indexes/search contiendra la copie de travail actuelle de l'index, indexes/update contiendra les anciennes copies ainsi que les mises à jour de l'index, etc...

Après cela vous pourrez effectuer des recherches par le biais de Lucene.

Exemple d'installation pas à pas sur Debian Etch
Sur une Debian fraichement installée, voici le cheminement à suivre : deb http://ftp.fr.debian.org/debian/ stable main contrib non-free deb-src http://ftp.fr.debian.org/debian/ stable main contrib non-free
 * 1) Installez l'extension LuceneSearch et modifiez votre LocalSettings.php
 * 2) Téléchargez le répertoire 'lucene-search-2' à partir du dépot SVN (voir dans l'infobox)
 * 3) Copier le dossier complet sur votre serveur, dans le répertoire /home/search/ls2 (renommer le dossier 'lucene-search-2' en 'ls2')
 * 4) Téléchargez la librairie mwdumper.jar et mettez là dans le dossier /home/search/ls2/lib
 * 5) Créez un dossier 'indexes' : mkdir /home/search/indexes
 * 6) Editez les fichiers 'lsearch.conf', 'lsearch-global.conf' et 'hostname' (hostname doit contenir le nom d'hôte tel qu'il apparait dans la variable d'environnement $HOSTNAME) comme indiqué au-dessus
 * 7) Installez ant :
 * 8) Installez classpath :
 * 9) Modifier le sources.list (dans /etc/apt) en non-free pour récupérer le jdk java qui va bien :
 * 1) Faite un ' '
 * 2) Vous devriez supprimer gij, sa présence à provoqué des problèmes dans mon installation, le démon ne voulant pas se lancer correctement :
 * 3) Installez le jdk java-sun :
 * 4) Intégrer le jdk au PATH :   et
 * 5) Aller dans le répertoire des sources de Lucene puis compiler avec ant :   puis
 * 6) On créé un premier index manuellement :   (n'oubliez pas de modifier les chemins vers votre wiki et d'éditer 'AdminSettings.php'...)
 * 7) On créé un cron pour lancer la commande précédente régulièrement (toutes les nuits, pour refléter les modifications des pages du wiki en cours de journée)
 * 8) On lance le démon dans un screen (pour pouvoir le détacher ensuite, et donc ne pas l'arrêter en fermant votre connexion ssh...) :
 * 9) C'est normalement bon, tout devrait fonctionner pour le mieux.

Incremental updates
If you feel that perdically rebuilding the index puts too much load on you database, you can use the incremental updater. It requires some additional work: php maintenance/dumpBackup.php --current --quiet > wikidb.xml && java -cp LuceneSearch.jar org.wikimedia.lsearch.ranks.RankBuilder wikidb.xml wikidb
 * 1) Install OAI extension for MediaWiki. This extension enables the incremental updater to fetch the latest articles.
 * 2) Create a new mysql database, e.g. lsearchdb and make sure it's an utf-8 database. It's needed to store the article ranking data. This data is normally recalculated by the importer at each import
 * 3) Setup Storage section in local configuration (lsearch.conf). Supply user and admin passwords for mysql db, admin passwords are needed for creation of tables, etc.
 * 4) Rebuild article rank data, You can put it on a cron job once a week, or once a month (article ranks typically change very slowly):
 * 1) Create the initial version of the index - you can do this using the importer described in previous sections

Finally, setup OAI repository for the incremental updater, in global config (lsearch-global.conf), setup a mapping of dbname : host, and in local settings supply username/password in OAI.username/password if any. Start incremental updater with: java -cp LuceneSearch.jar org.wikimedia.lsearch.oai.IncrementalUpdater -n -d -s 600 -dt start_time wikidb The parameters are:
 * -n - wait for notification from indexer that articles has been successfully added
 * -d - daemonize, i.e. run updates in an infinite loop
 * -s 600 - after one round of updates sleep 10 minutes (600s)
 * -dt timestamp - default timestamp (e.g. 2007-06-17T15:00:00Z) - This is the timestamp of your initial index build. You need to pass this parameter the first time you start the incremental updater, so it knows from what time to start the updates. Afterward the incremental updater will keep the timestamp of last successfull update in indexes/status/wikidb.

Alternative to (2),(3) and (4) is not to use ranking. You can do this by passing --no-ranks parameter to the incremental updater, and it won't try to fetch ranks from the mysql database. If your wiki is small and has some hundreds of pages, you probably don't need any ranking. But if you have or plan to have hundreds of thousands of pages, you will definitely benefit from ranking data.

So far we have only manage to incrementally update the index. To instruct the indexer to make a snapshot of index periodically (which get picked up by searchers), put this into your cron job: curl http://indexerhost:8321/makeSnapshots

Indexer has a command http interface. Other commands are getStatus, flushAll, etc ...

Distributed architecture
A common distribution is many searcher/one indexer approach. By a quick look at global config file (lsearch-global.conf) it should be obvious how to distribute searching. You just need to add more host : dbname mappings and startup lsearchd at those hosts. However, searchers need to be able to fetch and update their index, so:
 * 1) Setup rsyncd.conf and start the rsync daemon (there is sample config file in SVN) on the indexer host
 * 2) Add rsync path on the indexer host to global configuration in Index-Path section.

Restart everything (searchers and indexer) and they should now be aware of each other, searcher will periodically check for updates of indexes they are assigned. You need to run Importer at the indexer host, but you can run IncrementalUpdater at any host, since it will from global config know where the indexer is.

Split index
If your index is too big, and cannot fit into memory, you might want to split it up in smaller parts. There are a couple of ways to do this. Simplest way is to do mainsplit. This is split index into two parts, one with all articles in main namespace, and one for everything else. You can also do a nssplit, which will let split index by any combination of namespaces. Finally, there is a split architecture which randomly assigns documents to one of the N index parts. From performance viewpoint it's best to split index by namespaces, if possible as mainsplit. This is best if we assume the user almost always wants to search only the main namespace.

If you split index to many hosts, the usage will be load-balanced. E.g. at every search different combination of hosts having the required index parts will be searched. The MediaWiki Lucene Search extension doesn't need to worry about this, just have to get the request to host that has some part of the index.

There are examples of using these index architectures in lsearch-global.conf in the package.

Performance tuning
Default values for lucene indexer facilitate minimal memory usage and minimal number of segments. However, indexing might be very slow because of this. The default is 10 bufferred documents, and merge factor of 2. You might want to increase these values, for instance to 500 buffered docs, and merge factor of 20. You can do this in global configuration, e.g. wikidb : (single,true,20,500). Beware however that increasing number of buffered docs will quickly eat up heap. It's best to try out different values and see what are the best value for your memory profile.

If you run the searcher at a multi-CPU host, you might want to adjust SearcherPool.size in local config file. The pool size corresponds to number of IndexSearchers per index. You need to set it at least to number of CPUs, or better number of CPUs+1. This prevents CPUs from locking each other by accessing the index via single RandomAccessFile instance.