<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Wiizio &#187; Technique</title>
	<atom:link href="http://www.wiizio.com/category/technique/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.wiizio.com</link>
	<description>Solutions de recherche d&#039;entreprise open-source</description>
	<lastBuildDate>Thu, 06 Jan 2011 17:21:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Obtenir une compilation nocturne de Lucene 4.0 et Solr 4.0</title>
		<link>http://www.wiizio.com/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/</link>
		<comments>http://www.wiizio.com/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 18:15:09 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[Lucene]]></category>
		<category><![CDATA[nightly build]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=328</guid>
		<description><![CDATA[<p>Depuis le début de l&#8217;année les sources de Lucene et Solr ont fusionnées.  La prochaine version commune aura pour numéro 4.0. Pour ceux qui  veulent déjà tester la version en cours de développement, il faut en  récupérer les sources et les compiler. En effet, les liens de  téléchargement des compilations nocturnes <p>Lire la suite <a href="http://www.wiizio.com/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/">Obtenir une compilation nocturne de Lucene 4.0 et Solr 4.0</a></p>]]></description>
			<content:encoded><![CDATA[<p>Depuis le début de l&#8217;année les sources de Lucene et Solr ont fusionnées.  La prochaine version commune aura pour numéro 4.0. Pour ceux qui  veulent déjà tester la version en cours de développement, il faut en  récupérer les sources et les compiler. En effet, les liens de  téléchargement des compilations nocturnes ne fonctionnent pas. En  prérequis, il faut disposer de <strong>svn</strong> client et de <strong>ant</strong>.<span id="more-328"></span></p>
<p>Sur <a href="https://hudson.apache.org/hudson/job/Solr-trunk/" target="_blank">cette page</a>, il est possible de voir le statut de la dernière compilation nocturne. Si ce statut indique une compilation réussie, la procédure pour obtenir et compiler les sources est la suivante :</p>
<p>Créer un répertoire de travail :</p>
<pre>mkdir ~/solr-4.0
</pre>
<p>Se placer dans ce répertoire et récupérer les sources :</p>
<pre>cd ~/solr-4.0
svn checkout http://svn.apache.org/repos/asf/lucene/dev/trunk
</pre>
<p>Compiler les sources :</p>
<pre>cd ~/solr-4.0/modules
ant compile
cd ~/solr-4.0/lucene
ant dist
cd ~/solr-4.0/modules
ant dist</pre>
<p>Le tour est joué !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Indexation multi-lingues avec Lucene et Solr</title>
		<link>http://www.wiizio.com/2010/10/31/indexation-multi-lingues-avec-lucene-et-solr/</link>
		<comments>http://www.wiizio.com/2010/10/31/indexation-multi-lingues-avec-lucene-et-solr/#comments</comments>
		<pubDate>Sun, 31 Oct 2010 18:26:18 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[multilingues]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=322</guid>
		<description><![CDATA[<p>Un des challenges lors du passage de Fast ESP à Solr pour le moteur Hurisearch a été de pouvoir indexer et rechercher des documents dans un très grand nombre de langues. Plus de 60 langues sont répertoriées avec par exemple par ordre décroissant d&#8217;importance : Anglais, Espagnol, Français, Allemand, Flamand, Russe, Arabe, Slovène, Hébreux, Persan <p>Lire la suite <a href="http://www.wiizio.com/2010/10/31/indexation-multi-lingues-avec-lucene-et-solr/">Indexation multi-lingues avec Lucene et Solr</a></p>]]></description>
			<content:encoded><![CDATA[<p>Un des challenges lors du passage de <a href="http://www.microsoft.com/enterprisesearch/en/us/Fast.aspx" target="_blank">Fast ESP</a> à <a href="http://www.zoonix.fr/2008/09/18/presentation-de-lucene-solr/" target="_blank">Solr</a> pour le moteur <a href="http://www.hurisearch.org/">Hurisearch</a> a été de pouvoir indexer et rechercher des documents dans un très grand nombre de langues. Plus de 60 langues sont répertoriées avec par exemple par ordre décroissant d&#8217;importance : Anglais, Espagnol, Français, Allemand, Flamand, Russe, Arabe, Slovène, Hébreux, Persan (Farci), Coréen, Tchèque, Chinois, Norvégien, Japonais, Roumain, Catalan, Hongrois, Géorgien, &#8230;</p>
<p><strong>Lucene</strong> et différentes contributions permettent de disposer d&#8217;analyzer et même de &laquo;&nbsp;stemmer&nbsp;&raquo; pour un grand nombre de ces langues. Avec <strong>Solr</strong>, le seul moyen pour associer le bon analyzer à chaque langue est d&#8217;avoir autant de champs dans le shema qu&#8217;il y a de langues possibles et d&#8217;associer à chaque champ le bon analyzer. Pour <strong>Hurisearch</strong>, cela aurait donc fait 60 champs pour le contenu des documents et 60 champs pour les titres. L&#8217;autre problème dans ce cas est également de ne pas pouvoir chercher lors d&#8217;une même requête dans la totalité des langues  simultanément. Autant dire que ces contraintes et limitations ne sont pas acceptables.<span id="more-322"></span></p>
<p>Il est impératif d&#8217;utiliser un champ unique pour toutes les langues. Comme il est possible d&#8217;associer un seul analyzer à ce champ, ce dernier doit donc s&#8217;adapter à la langue du texte en cours d&#8217;indexation et à la langue de la requête (il faut également traiter la requête en fonction de sa langue). Deux analyzers ont donc été développés afin de traiter le texte au mieux en fonction de sa langue : un analyzer pour indexer le texte sans le &laquo;&nbsp;stemmer&nbsp;&raquo; et un en le &laquo;&nbsp;stemmant&nbsp;&raquo; lorsque cela est possible (<a href="http://en.wikipedia.org/wiki/Word_stem" target="_blank">voici une explication en anglais de ce qu&#8217;est un stem</a>).</p>
<p>Le dernier point à résoudre a été de trouver comment indiquer à l&#8217;analyzer la langue du texte qu&#8217;il va traiter. Avec <strong>Lucene</strong>, cela n&#8217;est pas un problème car les constructeurs (classes java) des analyzers  peuvent posséder une paramètre qui indique la langue. Par contre, avec <strong>Solr</strong>, cela n&#8217;est pas possible, les paramètres passés aux constructeurs des analyzers sont figés dans le fichier shema.xml. La solution a donc été de passer cette information en en-tête du texte lors de l&#8217;indexation et de la requête lors de la recherche.</p>
<p>En conclusion, nous avons été en mesure d&#8217;indexer un grand nombre de langues tout en pouvant rechercher simultanément dans tous les documents quelque soit leur langue et en offrant la possibilité de retrouver les mots indépendamment de leurs formes (genre, nombre, conjugaisons, &#8230;). Aujourd&#8217;hui, <strong>Hurisearch</strong> <a href="http://www.zoonix.fr/2010/03/07/un-crawler-web-pour-solr/">crawle</a> 5400 sites Web sites qui représentent plus de 10 millions de pages indexées pas <strong>Solr</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2010/10/31/indexation-multi-lingues-avec-lucene-et-solr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrader Lucene dans Solr 1.4</title>
		<link>http://www.wiizio.com/2010/10/31/upgrader-lucene-dans-solr-1-4/</link>
		<comments>http://www.wiizio.com/2010/10/31/upgrader-lucene-dans-solr-1-4/#comments</comments>
		<pubDate>Sun, 31 Oct 2010 18:10:44 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[Lucene]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=311</guid>
		<description><![CDATA[<p>Solr 1.4 utilise Lucene 2.9.0 et depuis sa sortie en novembre 2009, des mises à jours de Lucene sont disponibles. La dernière version de ce dernier est la 2.9.3. Afin de bénéficier de ces mises à jours dans Solr, il est possible de patcher le fichier solr.war. Les étapes pour réaliser ceci sont :</p>
<p>* créer <p>Lire la suite <a href="http://www.wiizio.com/2010/10/31/upgrader-lucene-dans-solr-1-4/">Upgrader Lucene dans Solr 1.4</a></p>]]></description>
			<content:encoded><![CDATA[<p>Solr 1.4 utilise Lucene 2.9.0 et depuis sa sortie en novembre 2009, des mises à jours de Lucene sont disponibles. La dernière version de ce dernier est la 2.9.3. Afin de bénéficier de ces mises à jours dans Solr, il est possible de patcher le fichier solr.war. <span id="more-311"></span>Les étapes pour réaliser ceci sont :</p>
<p>* créer un répertoire de travail</p>
<pre style="padding-left: 30px;">mkdir /tmp/solr</pre>
<p>* copier solr.war dans /tmp/solr</p>
<p>* extraire le contenu de solr.war et effacer solr.war</p>
<pre style="padding-left: 30px;">cd /tmp/solr
jar -xvf solr.war
rm solr.war</pre>
<p>* remplacer dans /tmp/solr/WEB-INF/lib tous les fichiers lucene-&#8230;-2.9.0.jar par leurs équivalents en version 2.9.3.</p>
<p>* astuce pour les utilisateurs de mac os, il faut supprimer les fichiers cachés &laquo;&nbsp;.DS_Store&nbsp;&raquo; qui ont été créés dans chaque répertoire</p>
<pre style="padding-left: 30px;">find . -name .DS* -print -exec rm -rf {} \;</pre>
<p>* reconstruire solr.war</p>
<pre style="padding-left: 30px;">jar cvf solr.war .</pre>
<p>Pour consulter la liste des évolutions et corrections depuis Lucene 2.9.0, vous pouvez consulter le &laquo;&nbsp;<a href="http://lucene.apache.org/java/2_9_2/changes/Changes.html" target="_blank">Lucene Change Log</a>&laquo;&nbsp;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2010/10/31/upgrader-lucene-dans-solr-1-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solr &#8211; Installation et configuration (2)</title>
		<link>http://www.wiizio.com/2009/10/17/solr-installation-et-configuration-2/</link>
		<comments>http://www.wiizio.com/2009/10/17/solr-installation-et-configuration-2/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 10:08:04 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[core]]></category>
		<category><![CDATA[jndi]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=91</guid>
		<description><![CDATA[




<p>Dans les précédents articles consacrés à Solr, j&#8217;en décris les principes (Présentation de Lucene Solr) et comment installer et configurer de façon très basique Solr afin de pouvoir indexer et rechercher dans le jeu de données de test fourni dans la distribution (Solr &#8211; Installation et configuration (1)).</p>
<p>Dans ce nouvel article, je vais expliquer plus <p>Lire la suite <a href="http://www.wiizio.com/2009/10/17/solr-installation-et-configuration-2/">Solr &#8211; Installation et configuration (2)</a></p>]]></description>
			<content:encoded><![CDATA[<table style="border-style: solid; border-width: 0pt; background-color: #ffffff;" border="0">
<tbody>
<tr style="background-color: #ffffff;" valign="top">
<td style="border-style: solid; border-width: 0px; background-color: #ffffff;"><img class="alignleft size-full wp-image-134" title="logo_home_solr" src="http://www.wiizio.com/wp-content/uploads/2009/10/logo_home_solr.jpg" alt="logo_home_solr" width="105" height="47" /></td>
<td style="border-style: solid; border-width: 0px; background-color: #ffffff;">
<p>Dans les précédents articles consacrés à <strong>Solr</strong>, j&#8217;en décris les principes (<a href="http://www.wiizio.com/2009/10/01/introduction-a-solr/">Présentation de Lucene Solr</a>) et comment installer et configurer de façon très basique <strong>Solr </strong>afin de pouvoir indexer et rechercher dans le jeu de données de test fourni dans la distribution (<a href="http://www.wiizio.com/2009/10/02/introduction-a-solr-installation-et-configuration-1/">Solr &#8211; Installation et configuration (1)</a>).</p>
<p>Dans ce nouvel article, je vais expliquer plus en détail les points suivants :</p>
<ul>
<li>Le contenu de la distribution</li>
<li>Les fichiers de configuration</li>
<li>Comment gérer plusieurs indexes ?</li>
<li>Comment gérer plusieurs applications ?</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p><span id="more-91"></span></p>
<h3>Le contenu de la distribution</h3>
<p>Une fois récupérée et décompressée dans un répertoire, la distribution de Solr contient différents répertoires.</p>
<table border="0">
<tbody>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Client</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Des API clientes pour Java (solrj) et Ruby (solr-ruby). Il existe en fait des solutions d&#8217;intégration avec d&#8217;autres langages (Perl, PHP, Python, C#, &#8230;). Une liste est disponible <a href="http://wiki.apache.org/solr/IntegratingSolr" target="_blank">ici </a>sur le wiki de Solr.</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Contrib</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">
<p>Des outils qui contribuent à étendre les fonctionnalités de Solr. Dans la distribution 1.3.0, il s&#8217;agit uniquement de l&#8217;outil dataimporthandler pour l&#8217;importation et l&#8217;indexation de données issues d&#8217;une base de données.</p>
<p>Dans les versions futures, il pourrait s&#8217;agir également d&#8217;un outil d&#8217;extraction du contenu de documents Office ou PDF (basé sur Tika), d&#8217;une intégration avec <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">Jsdoc Toolkit</a> et d&#8217;une intégration avec le <a href="http://velocity.apache.org/engine/index.html" target="_blank">framework Velocity</a>.</p>
</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Dist</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Les binaires issus de la compilation des sources de <strong>Solr </strong>et les librairies dont dépend <strong>Solr</strong>.</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Docs</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">La documentation de <strong>Solr</strong></td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Example</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Des exemples de mise en oeuvre et le nécessaire pour exécuter Solr avec Jetty. Les principaux sous-répertoires sont :</td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Multicore</strong></td>
</tr>
<tr>
<td></td>
<td style="width: 20px;"></td>
<td>Exemple de paramétrage en mode multi-core afin de gérer des applications et des index multiples dans une même webapp du serveur J2EE.</td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Solr</strong></td>
</tr>
<tr>
<td></td>
<td style="width: 20px;"></td>
<td>Exemple de répertoire &laquo;&nbsp;Home&nbsp;&raquo; de Solr et fichiers de configuration par défaut.</td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Webapps</strong></td>
</tr>
<tr>
<td></td>
<td style="width: 20px;"></td>
<td>Le fichier war à déployer dans la serveur J2EE et utiliser par le lanceur jetty fourni en exemple.</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Lib</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Les librairies java dont dépend <strong>Solr</strong></td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Src</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Les sources de <strong>Solr</strong></td>
</tr>
</tbody>
</table>
<p>Mettre en place un environnement d&#8217;exécution de Solr à partir des éléments de la distribution est très simple. Il faut :</p>
<ol>
<li>créer un environnement d&#8217;exécution en copiant le répertoire &laquo;&nbsp;/example/solr&nbsp;&raquo;, sous par exemple &laquo;&nbsp;/opt/solr&nbsp;&raquo; (Linux) ou &laquo;&nbsp;c:/solr&nbsp;&raquo; (windows) </li>
<li>copier le fichier solr.war contenu dans le répertoire webapps des exemples vers le répertoire approprié du serveur d&#8217;application (répertoire webapps par exemple pour Tomcat)</li>
<li>configurer le serveur d&#8217;application pour qu&#8217;il soit lancé avec la variable d&#8217;environnement solr.home.home pointant vers le répertoire d&#8217;exécution (par exemple : -Dsolr.solr.home=/opt/solr) et le redémarrer</li>
</ol>
<p>Dans le répertoire pointé par la variable d&#8217;environnement &laquo;&nbsp;solr.solr.home&nbsp;&raquo;, on retrouve donc les répertoires &laquo;&nbsp;bin&nbsp;&raquo; (scripts utilitaires pour un environnement Linux), &laquo;&nbsp;conf&nbsp;&raquo; (fichiers de configuration) et &laquo;&nbsp;data&nbsp;&raquo; (y sera entre autres localisés l&#8217;index Lucene des données indexées).</p>
<h3>Les fichiers de configuration</h3>
<p>Les fichiers de configuration sont localisés dans le répertoire &laquo;&nbsp;/conf&nbsp;&raquo;. Il s&#8217;agit principalement de solrconfig.xml et schema.xml.</p>
<h4>solrconfig.xml</h4>
<p>Il s&#8217;agit du fichier qui contient l&#8217;essentiel des paramètres liés au fonctionnement de Solr et plus particulièrement des paramètres de l&#8217;API Lucene qu&#8217;utilise Solr (longueur maximale d&#8217;une champs, taille des buffer mémoire, fréquence de commit, &#8230;) . Ce fichier est très bien auto-documenté et fait l&#8217;objet <a href="http://wiki.apache.org/solr/SolrConfigXml" target="_blank">d&#8217;un document a part entière dans le wiki Solr</a>.</p>
<h4>schema.xml</h4>
<p>Il s&#8217;agit du fichier qui décrit comment seront indexées les données dans Solr. Il définit les types de données, les champs, les manipulations sur les données lors de l&#8217;indexation, les champs obligatoires, le champ de requête par défaut, &#8230;</p>
<p>Ce fichier est très bien auto-documenté et fait l&#8217;objet <a href="http://wiki.apache.org/solr/SchemaXml" target="_blank">d&#8217;un document a part entiere dans le wiki Solr</a>.</p>
<h5>Exemple de déclaration d&#8217;un type</h5>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldType</span> <span style="color: #000066;">name</span>=”string” <span style="color: #000066;">class</span>=”solr.StrField” <span style="color: #000066;">sortMissingLast</span>=”true” <span style="color: #000066;">omitNorms</span>=”true”<span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Ce type a pour nom &laquo;&nbsp;string&nbsp;&raquo;, il sera pris en charge lors de l&#8217;indexation par la classe &laquo;&nbsp;solr.StrField&nbsp;&raquo;, lors d&#8217;un tri du résultat sur ce champ, les documents ne le possédant pas seront positionnés en dernier (sortMissingLast=&nbsp;&raquo;true&nbsp;&raquo;) et lors de l&#8217;indexation les informations de normalisation basées sur la taille du champ seront calculées et stockées (omitNorms=&nbsp;&raquo;true&nbsp;&raquo;).</p>
<h5>Exemple de déclaration d&#8217;un champ</h5>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;field</span> <span style="color: #000066;">name</span>=%u201Dword%u201D <span style="color: #000066;">type</span>=%u201Dstring%u201D <span style="color: #000066;">indexed</span>=%u201Dtrue%u201D <span style="color: #000066;">stored</span>=%u201Dtrue%u201D<span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Les données indexées dans <strong>Solr </strong>par le service d&#8217;indexation sont contenues dans un <a href="http://fr.wikipedia.org/wiki/Datagramme" target="_blank">datagramme </a>de type XML. Lorsque Solr traite ce datagramme, il rapproche le nom de chaque élément XML avec le nom d&#8217;un champ. Il manipule alors la donnée associé à cet élément comme cela est défini par la définition du champ.  <br class="spacer_" /> Ce champ est du type &laquo;&nbsp;string&nbsp;&raquo; (donc il hérite des propriétés de ce type). Il est indexé (donc les recherches peuvent porter sur son contenu) et les données de ce champs sont stokées (donc elles peuvent être récupérées au moment de l&#8217;affichage d&#8217;une liste de résultats par exemple).  D&#8217;autres paramètres importants peuvent également être définis lors de la déclaration d&#8217;un champ. Il s&#8217;agit de la méthode d&#8217;analyse lors de &#8216;indexation ou de la recherche. La méthode d&#8217;analyse permet de définir comment seront traitées les données du champ, à savoir son mode de découpage en mots (tokenizer) et les filtres qui lui seront appliqués (filter). Les filtres permettent par exemple de supprimer les mots vides, de mettre tous les mots en minuscule, de convertir les mots accentués en leurs équivalents sans accent, &#8230;</p>
<h5>Exemple de déclaration d&#8217;un champ dynamique</h5>
<p>Une déclaration de champ dynamique permet d&#8217;associer un traitement à des éléments du datagramme XML même si ces derniers ne sont pas spécifiquement déclarés comme champs.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dynamicField</span> <span style="color: #000066;">name</span>=%u201D*_s%u201D  <span style="color: #000066;">type</span>=%u201Dstring%u201D  <span style="color: #000066;">indexed</span>=%u201Dtrue%u201D  <span style="color: #000066;">stored</span>=%u201Dtrue%u201D<span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Tout élément du datagramme XML dont le nom se termine par &laquo;&nbsp;_s&nbsp;&raquo;, est considéré comme un élément de nom &laquo;&nbsp;string&nbsp;&raquo;.</p>
<h3>Comment gérer plusieurs indexes ?</h3>
<p>Par défaut, une instance Solr ne peut manipuler qu&#8217;un index. Comment faire si mon application doit permettre l&#8217;indexation de plusieurs types de données comme par exemple un annuaire de personnes et les messages d&#8217;un forum de discussion ?  Jusqu&#8217;à la version de 1.2 de Solr, il existait 2 solutions : associer un type à chaque document dans l&#8217;index (personne, message, &#8230;) ou utiliser plusieurs webapps dans le serveur J2EE et les faire pointer vers des environnements différents (-D=solr.solr.home=&#8230;). L&#8217;association d&#8217;un type à chaque document permet lors de la recherche de filtrer la liste de résultats en se limitant aux documents d&#8217;un ou plusieurs types. Utiliser plusieurs webapps permet d&#8217;utiliser un index distinct pour chaque type de documents.  Avec la version 1.3 de Solr est apparue la notion de &laquo;&nbsp;SolrCore&nbsp;&raquo; multiples. Un &laquo;&nbsp;SolrCore&nbsp;&raquo; est un environnement complet Solr (configuration et index) qui est exécuté par une webapps du serveur j2EE. Il est donc possible au moyen d&#8217;une seule webapps Solr de gérer plusieurs &laquo;&nbsp;SolrCore&nbsp;&raquo;. les SolrCore sont déclarés dans un fichier XML &laquo;&nbsp;solr.xml&nbsp;&raquo; localisé dans le répertoire solr.solr.home associé à la webapp. <br class="spacer_" /></p>
<h5>Exemple d&#8217;un environnement mono-core</h5>
<pre>solr.solr.home=/opt/solr  </pre>
<p>Les répertoires d&#8217;installation sont organisés comme ceci :</p>
<pre>/opt
    /solr
        /bin
        /conf
        /data
        /webapps
            solr.war
</pre>
<p>Pour un paramétrage de Tomcat au moyen de JNDI, on place dans le répertoire conf/Calalina/localhost de Tomcat, le fichier solr.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Context</span> <span style="color: #000066;">docBase</span>=<span style="color: #ff0000;">&quot;/opt/solr/webapps/solr.war&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">crossContext</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Environment</span></span>
<span style="color: #009900;">        <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;solr/home&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;java.lang.String&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;/opt/solr/&quot;</span> <span style="color: #000066;">override</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Context<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr sont :</p>
<table border="1">
<tbody>
<tr>
<td>Administration</td>
<td>=&gt;</td>
<td>http://&lt;server&gt;:&lt;port&gt;/solr/admin/</td>
</tr>
<tr>
<td>Indexation / suppression</td>
<td>=&gt;</td>
<td>http://&lt;server&gt;:&lt;port&gt;/solr/update</td>
</tr>
<tr>
<td>Recherche</td>
<td>=&gt;</td>
<td>http://&lt;server&gt;:&lt;port&gt;/solr/select</td>
</tr>
</tbody>
</table>
<h5>Exemple d&#8217;un environnement multi-core</h5>
<p>solr.solr.home=/opt/solr</p>
<p>Les répertoires d&#8217;installation sont organisés comme ceci :</p>
<p>/opt</p>
<pre>    /solr
        solr.xml
        /core0
            /bin
            /conf
            /data
        /core1
            /bin
            /conf
            /data
        /webapps
            solr.war
</pre>
<p>Pour un paramétrage de Tomcat au moyen de JNDI, on place dans le répertoire conf/Calalina/localhost de Tomcat, le fichier solr.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Context</span> <span style="color: #000066;">docBase</span>=<span style="color: #ff0000;">&quot;/opt/solr/webapps/solr.war&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">crossContext</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Environment</span></span>
<span style="color: #009900;">        <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;solr/home&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;java.lang.String&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;/opt/solr/&quot;</span> <span style="color: #000066;">override</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Context<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Dans le répertoire pointé par solr.solr.home, on place de féchier solr.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;solr</span> <span style="color: #000066;">persistent</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">sharedLib</span>=<span style="color: #ff0000;">&quot;lib&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;cores</span> <span style="color: #000066;">adminPath</span>=<span style="color: #ff0000;">&quot;/admin/cores&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;core</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;core0&quot;</span> <span style="color: #000066;">instanceDir</span>=<span style="color: #ff0000;">&quot;core0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;core</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;core1&quot;</span> <span style="color: #000066;">instanceDir</span>=<span style="color: #ff0000;">&quot;core1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/cores<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/solr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr des cores 0 et 1 sont :</p>
<table border="1">
<tbody>
<tr>
<td valign="top">Administration</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/solr/core0/admin/ <br />
 http://&lt;server&gt;:&lt;port&gt;/solr/core1/admin/</td>
</tr>
<tr>
<td valign="top">Indexation / suppression</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/solr/core0/update <br />
 http://&lt;server&gt;:&lt;port&gt;/solr/core1/update</td>
</tr>
<tr>
<td valign="top">Recherche</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/solr/core0/select  <br />
 http://&lt;server&gt;:&lt;port&gt;/solr/core1/select</td>
</tr>
</tbody>
</table>
<p><br class="spacer_" /></p>
<h3>Comment gérer plusieurs applications ?</h3>
<p>Imaginons que vous souhaitez indexer des données issues de différentes applications, pour l&#8217;exemple, un outil de gestion de contenu (ECM) et un forum de discussion. Chacune de ces applications nécessitant l&#8217;indexation de 2 types de données totalement différentes, pour l&#8217;exemple, des utilisateurs et des documents (ECM) ou des messages (forum).</p>
<p>Dans ce cas, je propose d&#8217;utiliser une webapp par application et un core par type de données.</p>
<p>On a donc un environnement comme celui-ci :</p>
<pre>solr.solr.home=/opt/solr</pre>
<p>Les répertoires d&#8217;installation sont organisés comme ceci :</p>
<p>/opt</p>
<pre>    /solr
        /ecm
            solr.xml
            /utilisateurs
                /bin
                /conf
                /data
            /documents
                /bin
                /conf
                /data
        /forum
            solr.xml
            /utilisateurs
                /bin
                /conf
                /data
            /messages
                /bin
                /conf
                /data
        /webapps
            solr.war
</pre>
<p>Pour un paramétrage de Tomcat au moyen de JNDI, on place dans le répertoire conf/Calalina/localhost de Tomcat, le fichier ecm.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Context</span> <span style="color: #000066;">docBase</span>=<span style="color: #ff0000;">&quot;/opt/solr/webapps/solr.war&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">crossContext</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Environment</span></span>
<span style="color: #009900;">        <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;solr/home&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;java.lang.String&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;/opt/solr/ecm&quot;</span> <span style="color: #000066;">override</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Context<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>et le fichier forum.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Context</span> <span style="color: #000066;">docBase</span>=<span style="color: #ff0000;">&quot;/opt/solr/webapps/solr.war&quot;</span> <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">crossContext</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Environment</span></span>
<span style="color: #009900;">        <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;solr/home&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;java.lang.String&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;/opt/solr/forum&quot;</span> <span style="color: #000066;">override</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Context<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Dans le répertoire &laquo;&nbsp;/opt/solr/ecm&nbsp;&raquo;, on place de fichier solr.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;solr</span> <span style="color: #000066;">persistent</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">sharedLib</span>=<span style="color: #ff0000;">&quot;lib&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;cores</span> <span style="color: #000066;">adminPath</span>=<span style="color: #ff0000;">&quot;/admin/cores&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;core</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;utilisateurs&quot;</span> <span style="color: #000066;">instanceDir</span>=<span style="color: #ff0000;">&quot;utilisateurs&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;core</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;documents&quot;</span> <span style="color: #000066;">instanceDir</span>=<span style="color: #ff0000;">&quot;documents&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/cores<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/solr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Dans le répertoire &laquo;&nbsp;/opt/solr/forum&nbsp;&raquo;, on place de fichier solr.xml suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;solr</span> <span style="color: #000066;">persistent</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">sharedLib</span>=<span style="color: #ff0000;">&quot;lib&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;cores</span> <span style="color: #000066;">adminPath</span>=<span style="color: #ff0000;">&quot;/admin/cores&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;core</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;utilisateurs&quot;</span> <span style="color: #000066;">instanceDir</span>=<span style="color: #ff0000;">&quot;utilisateurs&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;core</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;messages&quot;</span> <span style="color: #000066;">instanceDir</span>=<span style="color: #ff0000;">&quot;messages&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/cores<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/solr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr de l&#8217;application ECM sont :</p>
<table border="1">
<tbody>
<tr>
<td valign="top">Administration</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/ecm/utilisteurs/admin/ <br />
 http://&lt;server&gt;:&lt;port&gt;/ecm/documents/admin/</td>
</tr>
<tr>
<td valign="top">Indexation / suppression</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/ecm/utilisteurs/update <br />
 http://&lt;server&gt;:&lt;port&gt;/ecm/documents/update</td>
</tr>
<tr>
<td valign="top">Recherche</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/ecm/utilisteurs/select  <br />
 http://&lt;server&gt;:&lt;port&gt;/ecm/documents/select</td>
</tr>
</tbody>
</table>
<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr de l&#8217;application Forum sont :</p>
<table border="1">
<tbody>
<tr>
<td valign="top">Administration</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/forum/utilisteurs/admin/ <br />
 http://&lt;server&gt;:&lt;port&gt;/forum/messages/admin/</td>
</tr>
<tr>
<td valign="top">Indexation / suppression</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/forum/utilisteurs/update <br />
 http://&lt;server&gt;:&lt;port&gt;/forum/messages/update</td>
</tr>
<tr>
<td valign="top">Recherche</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/forum/utilisteurs/select  <br />
 http://&lt;server&gt;:&lt;port&gt;/forum/messages/select</td>
</tr>
</tbody>
</table>
<p>Sous Linux, une optimisation peut être de factoriser le répertoire &laquo;&nbsp;bin&nbsp;&raquo; de chaque core car il contient exactement les mêmes scripts. On place un répertoire &laquo;&nbsp;bin&nbsp;&raquo; dans &laquo;&nbsp;/opt/solr&nbsp;&raquo; et dans chaque core, on créer un lien symbolique nommé &laquo;&nbsp;bin&nbsp;&raquo; et qui pointe sur &laquo;&nbsp;/opt/solr/bin&nbsp;&raquo;.</p>
<p>Pour synthétiser les différents cas de figure lors du choix d&#8217;une configuration de Solr, voici un tableau récapitulatif.</p>
<table border="1">
<tbody>
<tr valign="top">
<td valign="top">Une seule application avec un seul type de données à indexer</td>
<td>=&gt;</td>
<td valign="top">1 webapp, pas de SolrCore</td>
</tr>
<tr valign="top">
<td>Une seule application avec plusieurs types de données très similaires. Par exemple, des articles de presse, des dossiers, des rapport, des études, &#8230; qui ont tous des meta-données communes (titre, auteur, date de publication et contenu)</td>
<td>=&gt;</td>
<td>1 webapp, pas de SolrCore mais une donnée qualifiant le type permettant le filtrage de la liste de résultat sur une ou plusieurs de ces valeurs.</td>
</tr>
<tr valign="top">
<td>Une seule application avec plusieurs types de données sans similarité (documents, utilisateurs, &#8230;)</td>
<td>=&gt;</td>
<td>1 webapp et des SolsCore pour indexer les différents types de données dans des index disctincts</td>
</tr>
<tr valign="top">
<td>Plusieurs applications (ECM, Forum, messagerie).</td>
<td>=&gt;</td>
<td>1 webapp par application avec ou sans SolrCore multiple en fonction des données à indexer pour chacune des applications (voir les cas précédents)</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2009/10/17/solr-installation-et-configuration-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solr &#8211; Installation et configuration (1)</title>
		<link>http://www.wiizio.com/2009/10/02/introduction-a-solr-installation-et-configuration-1/</link>
		<comments>http://www.wiizio.com/2009/10/02/introduction-a-solr-installation-et-configuration-1/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 09:29:46 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=123</guid>
		<description><![CDATA[




<p>Suite au premier article Présentation de Lucene Solr, voici un article sur la mise en oeuvre de ce moteur de recherche. Les différents sujets abordés seront :</p>

L&#8217;installation 
La configuration
L&#8217;indexation
La recherche





<p>Cette première partie a pour but l&#8217;installation et la configuration minimum afin de pouvoir rechercher dans les documents d&#8217;exemple fournis dans la distribution de Solr.</p>
Pré-requis

Installer Java <p>Lire la suite <a href="http://www.wiizio.com/2009/10/02/introduction-a-solr-installation-et-configuration-1/">Solr &#8211; Installation et configuration (1)</a></p>]]></description>
			<content:encoded><![CDATA[<table style="border-style: solid; border-width: 0pt; background-color: #ffffff;" border="0">
<tbody>
<tr style="background-color: #ffffff;" valign="top">
<td style="border-style: solid; border-width: 0px; background-color: #ffffff;"><img class="alignleft size-full wp-image-134" title="logo_home_solr" src="http://www.wiizio.com/wp-content/uploads/2009/10/logo_home_solr.jpg" alt="logo_home_solr" width="105" height="47" /></td>
<td style="border-style: solid; border-width: 0px; background-color: #ffffff;">
<p>Suite au premier article <a href="http://www.wiizio.com/2009/10/01/introduction-a-solr/">Présentation de Lucene Solr</a>, voici un article sur la mise en oeuvre de ce moteur de recherche<a href="http://lucene.apache.org/solr/" target="_blank"></a>. Les différents sujets abordés seront :</p>
<ul>
<li>L&#8217;installation </li>
<li>La configuration</li>
<li>L&#8217;indexation</li>
<li>La recherche</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Cette première partie a pour but l&#8217;installation et la configuration minimum afin de pouvoir rechercher dans les documents d&#8217;exemple fournis dans la distribution de <strong>Solr</strong>.<span id="more-123"></span></p>
<h3><strong>Pré-requis</strong></h3>
<ul>
<li>Installer Java 1.6 update 11 ou supérieur. Pour récupérer Java SE, c&#8217;est <a href="http://java.sun.com/javase/downloads/index.jsp" target="_blank">ici</a>. </li>
<li>Installer <a href="http://tomcat.apache.org/index.html" target="_blank">Tomcat</a>. Pour récupérer Tomcat 5.5, c&#8217;est <a href="http://tomcat.apache.org/download-55.cgi" target="_blank">ici</a>.</li>
<li>Récupérer une distribution de Solr. C&#8217;est <a href="http://www.apache.org/dyn/closer.cgi/lucene/solr/" target="_blank">ici pour la version officielle</a> et <a href="http://people.apache.org/builds/lucene/solr/nightly/" target="_blank">ici et pour les derniers builds nocturnes</a>.</li>
</ul>
<h3><strong>Installation</strong></h3>
<p>Décompresser l&#8217;archive dans un répertoire de travail. Pour cet article, il s&#8217;agit de &laquo;&nbsp;d:\solr&nbsp;&raquo;. Un sous-répertoire est créé. Selon la version de Solr que vous aurez récupéré, ce répertoire peut s&#8217;appeller &laquo;&nbsp;apache-solr-nightly&nbsp;&raquo; ou &laquo;&nbsp;apache-solr-1.4.0&#8243;. Je suggère donc pour simplifier de renommer ce répertoire en &laquo;&nbsp;apache-solr&nbsp;&raquo;.</p>
<p><strong>Configurer Solr pour un fonctionnement avec Jetty</strong></p>
<p>Pour faire fonctionner avec la version de <strong>Jetty </strong>fournie avec <strong>Solr</strong>, il n&#8217;y a pas vraiment de configuration. Pour démarrer <strong>Jetty</strong>, il faut ouvrir une console et se placer dans le répertoire &laquo;&nbsp;d:\solr\apache-solr\example&nbsp;&raquo; et exécuter la commande suivante :</p>
<pre><code>java -jar start.jar</code></pre>
<p>Une fois que vous voyer apparaître la ligne suivante, le serveur est démarré :</p>
<pre>INFO: [] Registered new searcher Searcher@d642fd main</pre>
<p>On accède alors à l&#8217;administration de Solr avec l&#8217;url suivante :</p>
<pre>http://localhost:8983/solr/admin</pre>
<p>Pour une utilisation avec une instance existante de <strong>Jetty</strong>, la page du wiki qui explique la configuration est <a href="http://wiki.apache.org/solr/SolrJetty" target="_blank">ici</a>.</p>
<p><strong>Configurer Solr pour un fonctionnement sous Tomcat 5.5</strong></p>
<p>1. Afin de pouvoir passer en mode HTTP-GET des critères de recherche utilisant des caractères internationaux (code supérieur à 127) il est nécessaire d&#8217;éditer le fichier conf/server.xml de <strong>Tomcat </strong>et d&#8217;ajouter l&#8217;attribut suivant à l&#8217;élément Connector approprié : <code>URIEncoding="UTF-8"</code>.</p>
<p>Il s&#8217;agit à priori du connecteur correspondant au port 8080, ce qui donne quelque chose comme ceci :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Connector</span> <span style="color: #000066;">port</span>=<span style="color: #ff0000;">&quot;8080&quot;</span> <span style="color: #000066;">maxHttpHeaderSize</span>=<span style="color: #ff0000;">&quot;8192&quot;</span> <span style="color: #000066;">maxThreads</span>=<span style="color: #ff0000;">&quot;150&quot;</span></span>
<span style="color: #009900;"> <span style="color: #000066;">minSpareThreads</span>=<span style="color: #ff0000;">&quot;25&quot;</span> <span style="color: #000066;">maxSpareThreads</span>=<span style="color: #ff0000;">&quot;75&quot;</span> <span style="color: #000066;">enableLookups</span>=<span style="color: #ff0000;">&quot;false&quot;</span></span>
<span style="color: #009900;"> <span style="color: #000066;">redirectPort</span>=<span style="color: #ff0000;">&quot;8443&quot;</span> <span style="color: #000066;">acceptCount</span>=<span style="color: #ff0000;">&quot;100&quot;</span> <span style="color: #000066;">connectionTimeout</span>=<span style="color: #ff0000;">&quot;20000&quot;</span></span>
<span style="color: #009900;"> <span style="color: #000066;">disableUploadTimeout</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">URIEncoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>2. Copier le fichier &laquo;&nbsp;d:\solr\apache-solr\example\webapps\solr.war&nbsp;&raquo; dans le répertoire webapps de Tomcat.</p>
<p>3. Au moyen de la console <strong>Tomcat </strong>(dans le system tray), ajouter le paramètre</p>
<pre>-Dsolr.solr.home=d:\solr\apache-solr\example\solr</pre>
<p>4. Redémarrer Tomcat.</p>
<p>On accède alors à l&#8217;administration de <strong>Solr </strong>avec l&#8217;url suivante :</p>
<pre>http://localhost:8080/solr/admin</pre>
<h3>Indexer un jeu de données en exemple</h3>
<p>La distribution de <strong>Solr </strong>inclue un jeu de documents de test pour l&#8217;indexation. Il est possible de les indexer au moyen du package java post.jar.</p>
<p>Ouvrir une console et se placer dans le répertoire &laquo;&nbsp;d:\solr\apache-solr\example\exampledocs&nbsp;&raquo;</p>
<p>Avec Jetty, lancer la commande :</p>
<pre>java -jar post.jar *.xml</pre>
<p>Avec Tomcat, lancer la commande :</p>
<pre>java -Durl=http://localhost:8080/solr/update -jar post.jar *.xml</pre>
<p>Pour obtenir la liste de toutes les options de cet utilitaire, la commande est :</p>
<pre>java -jar post.jar -help </pre>
<h3>Exécuter des recherches</h3>
<p><strong>Solr </strong>est maintenant fonctionnel et des données sont indexées. Il est donc possible d&#8217;exécuter les premières recherches avec le formulaire suivant :</p>
<pre>http://localhost:8080/solr/admin/form.jsp</pre>
<p>Vous pouvez constater que les résultats sont fournis au format XML. C&#8217;est effectivement à l&#8217;application appelant <strong>Solr </strong>de mettre en forme ces résultats.</p>
<h3>Conclusion</h3>
<p>Dans cet article, nous avons installé et fait fonctionné <strong>Solr </strong>dans un environnement <strong>Tomcat</strong> sous Windows. Par la suite j&#8217;aborderai plus en détail la configuration, les options de recherche et l&#8217;exploitation des résultats.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2009/10/02/introduction-a-solr-installation-et-configuration-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Créer un nuage de tags avec Lucene</title>
		<link>http://www.wiizio.com/2009/10/01/creer-un-nuage-de-tags-avec-lucene/</link>
		<comments>http://www.wiizio.com/2009/10/01/creer-un-nuage-de-tags-avec-lucene/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 19:57:04 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[Lucene]]></category>
		<category><![CDATA[nuage de tags]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=88</guid>
		<description><![CDATA[<p></p>
<p>Dans cet article, je présente une solution afin de générer un nuage de tags (ou nuage de mots clefs) à partir d’un flux de données textuelles. Pour l’exemple, il s’agit de titres d’articles stockés dans un fichier texte.</p>
<p>Le but est d’afficher les mots ou expressions de 2 ou 3 termes les plus fréquents dans les <p>Lire la suite <a href="http://www.wiizio.com/2009/10/01/creer-un-nuage-de-tags-avec-lucene/">Créer un nuage de tags avec Lucene</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/tagcloud.jpg"><img class="alignleft size-medium wp-image-44" src="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/tagcloud.jpg" alt="" width="90" height="90" /></a></p>
<p>Dans cet article, je présente une solution afin de générer un <a href="http://fr.wikipedia.org/wiki/Nuage_de_mots_clefs" target="_blank">nuage de tags</a> (ou nuage de mots clefs) à partir d’un flux de données textuelles. Pour l’exemple, il s’agit de titres d’articles stockés dans un fichier texte.</p>
<p>Le but est d’afficher les mots ou expressions de 2 ou 3 termes les plus fréquents dans les titres. Tous les termes ou expressions ne sont pas à conserver dans le nuage de tag. Une des étapes consiste en un filtrage selon des règles définies dans fichiers de règles : suppression des mots vides (je, le, pour, …), suppression des expressions commençant ou se terminant par un mot vide (”ne mange”, “termes les”, …), suppression des nombres, …<span id="more-88"></span></p>
<p>Les étapes nécessaires à la mise en œuvre de cette solution sont :</p>
<ul>
<li>Etape 1 : indexation des titres dans Lucene</li>
<li>Etape 2 : extraction des termes ou expressions de l’index</li>
<li>Etape 3 : filtrage des termes ou expressions</li>
<li>Etape 4 : affichage du nuage en PHP</li>
</ul>
<p>Les 3 premières étapes sont réalisées en java avec Lucene et donne comme résultat un fichier de termes ou expressions retenues dans le nuage de tags avec leur fréquence d’apparition.</p>
<p>La 4ème étape est réalisée en PHP et exploite le fichier résultat des étapes précédentes afin de mettre en forme le nuage de tags.</p>
<h3>Pourquoi utiliser Lucene (étapes 1 et 2) ?</h3>
<p>La génération du nuage de tags nécessite 2 étapes que Lucene est à même de réaliser : analyser et découper le texte servant à générer le nuage de tags et indiquer la fréquence d’apparition de chaque mot ou expression.</p>
<p>Lucene utilise des analyzers afin d’indexer le texte. Ces analyzers ont pour rôle principal de découper le texte en « token ». Selon les analyzers utilisés les tokens sont séparés par des espaces, des ponctuations, des caractères spéciaux (#, @, …), des chiffres, …</p>
<p>Par exemple, pour la phrase suivante : « Parcours du Tour de France », les tokens seraient sans doute : « parcours », « du », « tour », « de » et « France ».</p>
<p>Dans notre nuage de tags, nous ne voulons pas uniquement des mots simples, mais également des expressions de 2 ou 3 mots. Il nous faut donc extraire toutes les combinaisons possibles de tokens de 1, 2 ou 3 mots, c&#8217;est-à-dire : « parcours », « du », « tour », « de », « France », « parcours du », « du tour », « tour de », « de France », « parcours du tour », « du tour de » et « tour de France »</p>
<p>Un analyzer permettant de faire cela est disponible non pas dans la distribution standard de Lucene, mais à l’adresse suivante : <a href="http://issues.apache.org/jira/browse/LUCENE-400" target="_blank">http://issues.apache.org/jira/browse/LUCENE-400</a>. Inutile de récupérer cet analyzer, j’en fournie les sources modifiés afin de fonctionner avec Lucene 2.3.2</p>
<p>Pour une présentation plus complète de Lucene, voir mon article &laquo;&nbsp;<a href="http://www.zoonix.fr/2008/08/06/introduction-a-lucene/">Introduction à Lucene</a>&laquo;&nbsp;.</p>
<h3>Pourquoi filtrer les termes ou expressions (étape 3) ?</h3>
<p>Dans l’exemple indiqué ci-dessus, les termes ou expressions obtenues sont : « parcours », « du », « tour », « de », « France », « parcours du », « du tour », « tour de », « de France », « parcours du tour », « du tour de » et « tour de France ». On remarque immédiatement des éléments que l’on ne souhaite pas voir apparaître dans le nuage : « du », « de », « parcours du », « du tour », « tour de », « de France » et « du tour de ». Il s&#8217;agit des mots-vides ou expression commençant ou se terminant par un mot-vide. Il reste donc les éléments suivants : « parcours », « France », « parcours du tour » et « tour de France ».</p>
<p>Nous pousserons le nettoyage jusqu&#8217;à supprimer les mots simples ou expressions apparaissants déjà dans une expression constituée de plus de mots. En effet, imaginons des données à analyser contenant une ou plusieurs fois les expressions suivantes : « tour de France », « tour d’Italie » et « tour d’Espagne », mais jamais ou peu de fois les mots « tour », « France », « Italie » et « Espagne » hors de ces expressions. Sans ce nettoyage, le nuage de tags contiendrait certainement « tour », « Italie », « France » et « Espagne » (très fréquents) et sans doute mais sans certitude « tour de France », « tour d’Italie » et « tour d’Espagne » (moins fréquents). Le nuage de tags serait alors complètement faux.</p>
<p>Ainsi nettoyé, le nuage devient « parcours du tour » et « tour de France » et est beaucoup plus pertinent que ce que nous avions obtenu avant le filtrage.</p>
<p>L’algorithme de nettoyage utilisant un fichier de règles est adapté de l’algorithme décrit dans l’article &laquo;&nbsp;<a href="http://richardfriedman.blogspot.com/2007/07/lucene-tag-cloud-generator.html" target="_blank">Lucene Tag Cloud Generator</a>&nbsp;&raquo; de <a href="http://richardfriedman.blogspot.com/" target="_blank">Richard Friedman</a>.</p>
<p>Le fichier de règles est principalement constituer de la liste des mots vides mais commence par 5 paramètres pouvant être désactivés (en mettant les lignes en commentaires avec un #). Il s’agit de :</p>
<ul>
<li>-smallwords : pour retirer les mots de 3 caractères ou moins</li>
<li>-numbers : pour retirer les nombres</li>
<li>-dashes : pour retirer les mots contenant un tiret (« &#8211; »)</li>
<li>-period : pour retirer les mots contenant un point</li>
<li>-include : pour retirer les mots ou expressions incluent dans une autre expression. J’ai mis cette option pour le principe, mais en la désactivant les résultats sont généralement très décevants.</li>
</ul>
<h3>Code source des étapes 1, 2 et 3</h3>
<p>Le code source java est disponible <a href="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/tagscloud.zip">ici</a> sous forme d’un projet <a href="http://www.eclipse.org/downloads/moreinfo/jee.php" target="_blank">Eclipse</a>. Il contient les fichiers suivants :</p>
<ul>
<li>NGramAnalyzerWrapper.java et NGramFilter.java (analyzer Lucene)</li>
<li>TagCloud.java (classe principale avec l’algorithme de filtrage)</li>
<li>input.txt (les données exemples à analyser)</li>
<li>rules.txt (le fichier de règles)</li>
</ul>
<p>Pour lancer l&#8217;analyse d&#8217;un fichier de données, l’usage est le suivant :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Usage<span style="color: #339933;">:</span> org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">demo</span>.<span style="color: #006633;">TagCloud</span> <span style="color: #339933;">-</span>input <span style="color: #009900;">&#91;</span>inputfile<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span>output <span style="color: #009900;">&#91;</span>outputfile<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span>rules <span style="color: #009900;">&#91;</span>rulesfile<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span>count <span style="color: #009900;">&#91;</span>count<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span>boost <span style="color: #009900;">&#91;</span>boost<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span>minfreq <span style="color: #009900;">&#91;</span>minfreq<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span>maxterm <span style="color: #009900;">&#91;</span>maxterm<span style="color: #009900;">&#93;</span>
&nbsp;
    input    <span style="color: #339933;">-</span> input file with data to be clouded
    output   <span style="color: #339933;">-</span> output file with cloud data
    rules    <span style="color: #339933;">-</span> rules file
    count    <span style="color: #339933;">-</span> max number of items within the cloud <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">default</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1000</span><span style="color: #009900;">&#41;</span>
    boost    <span style="color: #339933;">-</span> boost value <span style="color: #000000; font-weight: bold;">for</span> multi<span style="color: #339933;">-</span>terms tags <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">default</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
    minfreq  <span style="color: #339933;">-</span> minimum frequence <span style="color: #000000; font-weight: bold;">for</span> a ngram <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">default</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span>
    maxterms <span style="color: #339933;">-</span> maximum number of terms in expressions in the cloud <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">default</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>
&nbsp;
Example<span style="color: #339933;">:</span> java org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">demo</span>.<span style="color: #006633;">TagCloud</span> <span style="color: #339933;">-</span>input <span style="color: #339933;">/</span>tmp<span style="color: #339933;">/</span>input.<span style="color: #006633;">txt</span> –output <span style="color: #339933;">/</span>tmp<span style="color: #339933;">/</span>output.<span style="color: #006633;">txt</span> <span style="color: #339933;">-</span>rules <span style="color: #339933;">/</span>tmp<span style="color: #339933;">/</span>rules.<span style="color: #006633;">txt</span> <span style="color: #339933;">-</span>count <span style="color: #cc66cc;">100</span> <span style="color: #339933;">-</span>boost <span style="color: #cc66cc;">1</span> <span style="color: #339933;">-</span>minfreq <span style="color: #cc66cc;">3</span> <span style="color: #339933;">-</span>maxterm <span style="color: #cc66cc;">4</span></pre></div></div>

<h3>Etape 4 : affichage du nuage en PHP</h3>
<p>La mise en forme du nuage de tags utilise le fichier généré par le programme précédent. Une classe PHP réalise cette mise en forme (lecture du fichier et génération du code html) et une feuille de style définie les styles d’affichage.</p>
<p>La classe PHP est une adaptation du code proposé dans l’article &laquo;&nbsp;<a href="http://www.hawkee.com/snippet/1485/" target="_blank">Tagcloud Font Distributor</a>&laquo;&nbsp;.</p>
<p>Le code source disponible <a href="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/tagscloudweb.zip">ici</a> est constitué des fichiers suivants :</p>
<ul>
<li>cloud_tag.inc.php : la classe de génération du nuage de tags en html</li>
<li>tagcloud.css : la feuille de styles pour l&#8217;affichage de nuage de tags</li>
<li>cloud_tag_display.php : un script d&#8217;exemple utilisant la classe et la feuille de styles.</li>
</ul>
<h3>Résultats</h3>
<p>Voici quelques exemples de résultats obtenus à partir du fichier de données exemple et en faisant varier quelques paramètres.</p>
<h4>Exemple 1 : paramètres par défaut</h4>
<p style="text-align: center;"><a href="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/sample1.jpg"><img class="size-medium wp-image-44 aligncenter" src="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/sample1.jpg" alt="" width="462" height="361" /></a></p>
<h4>Exemple 2 : paramètres par défaut sauf boost = 3</h4>
<p>On remarque un plus grand nombre d&#8217;expressions de plus de 1 mot</p>
<p style="text-align: center;"><a href="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/sample2.jpg"><img class="size-medium wp-image-44 aligncenter" src="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/sample2.jpg" alt="" width="462" height="361" /></a></p>
<h4>Exemple 3 : paramètres par défaut sauf maxterm = 5 et boost = 5</h4>
<p>On remarque des expressions jusqu&#8217;à 5 mots et presque plus de mots seuls</p>
<p style="text-align: center;"><a href="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/sample3.jpg"><img class="size-medium wp-image-44 aligncenter" src="http://www.wiizio.com/wp-content/uploads/2009/10/tagcloud/sample3.jpg" alt="" width="462" height="361" /></a></p>
<h3>Stratégies de mise à jour du nuage de tags</h3>
<p>La stratégie de mise à jour du nuage de tags dépend de plusieurs paramètres :</p>
<ul>
<li>type de données (presse, forums, &#8230;)</li>
<li>la fréquence de mise à jour des données (chaque seconde, une fois par heure, une fois par jour, &#8230;)</li>
<li>le dynamisme que l&#8217;on veut donner au nuage</li>
</ul>
<p>Par exemple, pour des données peu changeantes et en faible quantité, on peut choisir de créer le nuage sur les données des 30 derniers jours avec régénération du nuage une fois par jour. Par contre, pour des données très changeantes comme un site de presse avec des données nouvelles toutes les secondes, on peut choisir de générer le nuage sur les données de la dernière journée voir des dernières heures avec régénération du nuage chaque heure voir chaque quart d&#8217;heure.</p>
<h3>Conclusions</h3>
<p>Je pense que des règles de filtrage basées sur des expressions régulières pourraient être ajoutées. Par exemple, une simple règle indiquant de ne pas accepter les mots avec des points ou des tirets remplacerait les règles &laquo;&nbsp;-dashes&nbsp;&raquo; et &laquo;&nbsp;-period&nbsp;&raquo;, une autre remplacerait &laquo;&nbsp;-number&nbsp;&raquo;. On pourrait mettre en place un grand nombre de règles supplémentaires comme par exemple le rejet des dates.</p>
<p>Je suis ouvert à toutes suggestions afin d&#8217;améliorer de la solution proposée.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2009/10/01/creer-un-nuage-de-tags-avec-lucene/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Présentation de Lucene Solr</title>
		<link>http://www.wiizio.com/2009/10/01/introduction-a-solr/</link>
		<comments>http://www.wiizio.com/2009/10/01/introduction-a-solr/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 19:55:28 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=80</guid>
		<description><![CDATA[<p></p>
<p>La nouvelle version 1.4.0 de Solr est enfin disponible. Cette sortie est l&#8217;occasion de présenter Solr à ceux qui ne le connaissent pas encore.</p>
<p>Solr (on prononce &#171;&#160;solar&#160;&#187;) est une outil open source permettant de mettre en place des fonctionnalités de recherche dans différents types d&#8217;applications et notamment des sites web (mais pas seulement). Solr est <p>Lire la suite <a href="http://www.wiizio.com/2009/10/01/introduction-a-solr/">Présentation de Lucene Solr</a></p>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-134" title="logo_home_solr" src="http://www.wiizio.com/wp-content/uploads/2009/10/logo_home_solr.jpg" alt="logo_home_solr" width="105" height="47" /></p>
<p>La nouvelle version <strong>1.4.0</strong> de <a href="http://lucene.apache.org/solr/">Solr</a> est enfin disponible. Cette sortie est l&#8217;occasion de présenter <strong>Solr </strong>à ceux qui ne le connaissent pas encore.</p>
<p><strong>Solr </strong>(on prononce &laquo;&nbsp;solar&nbsp;&raquo;) est une outil open source permettant de mettre en place des fonctionnalités de recherche dans différents types d&#8217;applications et notamment des sites web (mais pas seulement). <strong>Solr </strong>est basé sur <a href="http://lucene.apache.org/" target="_blank">Lucene</a> qui est présenté dans un <a href="http://www.wiizio.com/2009/10/01/introduction-a-lucene/">précédent article</a>. Cette nouvelle version bénéficie des dernières évolutions de Lucene 2.9.</p>
<p><span id="more-80"></span></p>
<p>Comme <strong>Lucene</strong>, <strong>Solr </strong>est développé en Java. Il étend les fonctionnalités de Lucene et en simplifie la mise en oeuvre. <strong>Sorl </strong>fournit principalement 3 choses :</p>
<ul>
<li>un web service d&#8217;indexation des données</li>
<li>un web service de recherche</li>
<li>une interface web d&#8217;administration</li>
</ul>
<p>Avec <strong>Solr</strong>, les documents sont ajoutés à une collection via <strong>&laquo;&nbsp;XML over HTTP&nbsp;&raquo;</strong> (une requête HTTP en mode POST qui envoit des données XML décrivant le document à indexer), et les recherches sont faites avec au moyen d&#8217;une requête HTTP qui retourne un résultat au format XML (les documents correspondants à la requête). Le traitement des requêtes HTTP par Solr se fait au moyen d&#8217;une servlet (installé sous <a href="http://tomcat.apache.org/" target="_blank">Tomcat </a>par exemple).</p>
<p>Les 3 principaux avantages à utiliser Solr et non pas Lucene seul sont :</p>
<ul>
<li>Le fonctionnement en mode services WEB (<a href="http://fr.wikipedia.org/wiki/Representational_state_transfer" target="_blank">REST</a>), c&#8217;est à dire, la possibilité d&#8217;indexer et de rechercher des documents sans la moindre ligne de code si ce n&#8217;est la construction des données XML pour l&#8217;indexation et l&#8217;exploitation des données XML retournées par une recherche</li>
<li>l&#8217;utilisation dans des applications écrites dans n&#8217;importe quel langage et permettant de communiquer en HTTP</li>
<li>Solr étend et optimise Lucene (performances, analyseurs de texte, monitoring, &#8230;)</li>
</ul>
<p>Les fonctionnalité principales ajoutées à Lucene sont :</p>
<ul>
<li>Configuration au moyen de fichiers XML</li>
<li>Mise en évidence des termes trouvés (Hit highlighting)</li>
<li>Navigateurs dans les résultats (Faceted search)</li>
<li>Gestion de cache</li>
<li>Une interface d&#8217;administration Web</li>
<li>Architecture extensible basée sur des plugin</li>
<li>Optimisation pour des hauts trafics Web</li>
<li>Statistiques</li>
</ul>
<p>Pour comprendre le fonctionnement de Solr, je vous conseil ces articles (en anglais) :</p>
<ul>
<li><a href="http://lucene.apache.org/solr/tutorial.html" target="_blank">Le tutorial de Solr</a></li>
<li><a href="http://www.xml.com/pub/a/2006/08/09/solr-indexing-xml-with-lucene-andrest.html?page=1" target="_blank">Solr: Indexing XML with Lucene and REST</a></li>
<li><a href="http://www.trijug.org/downloads/TriJug-11-07.pdf" target="_blank">Une première présentation sous forme de slides</a></li>
<li><a href="http://www.slideshare.net/bdelacretaz/beyond-fulltext-searches-with-lucene-and-solr" target="_blank">Une seconde présentation sous forme de slides</a></li>
</ul>
<p>Voici une série de 3 articles (toujours en anglais) d&#8217;une très grande qualité écrit par <a href="http://lucene.grantingersoll.com/" target="_blank">Grant Ingersoll</a>. Les 2 premiers articles sont une présentation détaillée de <strong>Solr </strong>et le troisième présente les nouveautés de la version 1.3 sortie en septembre 2008.</p>
<p>Mai et Juin 2007 :</p>
<ul>
<li><a href="http://www.ibm.com/developerworks/java/library/j-solr1/index.html?S_TACT=105AGX02&amp;S_CMP=EDU" target="_blank">Search smarter with Apache Solr, Part 1: Essential features and the Solr schema</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-solr2/index.html?S_TACT=105AGX02&amp;S_CMP=EDU" target="_blank">Search smarter with Apache Solr, Part 2: Solr for the enterprise</a></li>
</ul>
<p>Septembre 2008 :</p>
<ul>
<li><a href="http://www.ibm.com/developerworks/java/library/j-solr-update/?S_TACT=105AGX01&amp;S_CMP=HP" target="_blank">What&#8217;s new with Apache Solr</a> (1.3)<a href="http://www.ibm.com/developerworks/java/library/j-solr-update/?S_TACT=105AGX01&amp;S_CMP=HP" target="_blank"><br />
 </a></li>
</ul>
<p>Bonne lecture.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2009/10/01/introduction-a-solr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction à Lucene</title>
		<link>http://www.wiizio.com/2009/10/01/introduction-a-lucene/</link>
		<comments>http://www.wiizio.com/2009/10/01/introduction-a-lucene/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 19:55:10 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>
		<category><![CDATA[Lucene]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=78</guid>
		<description><![CDATA[<p>Lucene est une librairie open source en Java (mais il existe de nombreux portages) permettant d&#8217;ajouter des fonctionnalités de recherche plein-texte à vos applications. Le projet Lucene est chapeauté par &#171;&#160;The Apache Software Foundation&#160;&#187;. D&#8217;autres projets très connus et de grande qualité de la fondation sont : Apache HTTP server, Tomcat, Cocoon, Ant, &#8230;</p>
<p>Il s&#8217;agit <p>Lire la suite <a href="http://www.wiizio.com/2009/10/01/introduction-a-lucene/">Introduction à Lucene</a></p>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-160" title="logo_lucene" src="http://www.wiizio.com/wp-content/uploads/2009/10/logo_lucene.jpg" alt="logo_lucene" width="170" height="23" /><a href="http://lucene.apache.org/" target="_blank">Lucene</a> est une librairie open source en Java (mais il existe de nombreux portages) permettant d&#8217;ajouter des fonctionnalités de recherche plein-texte à vos applications. Le projet Lucene est chapeauté par <a href="http://www.apache.org/" target="_blank">&laquo;&nbsp;The Apache Software Foundation&nbsp;&raquo;</a>. D&#8217;autres projets très connus et de grande qualité de la fondation sont : Apache HTTP server, Tomcat, Cocoon, Ant, &#8230;</p>
<p>Il s&#8217;agit bien d&#8217;une librairie avec laquelle il n&#8217;est pas fourni d&#8217;outils permettant l&#8217;indexation de données en quelques clics de souris et quelques paramétrages. Il faut donc en passer par du code Java afin de mettre en place une solution sur mesure de recherche plein-texte.<span id="more-78"></span></p>
<h3>Principe</h3>
<p>Lucene indexe et retrouve des &laquo;&nbsp;documents&nbsp;&raquo;. Par document, on ne parle pas de fichiers Excel, Word, PDF ou HTML, mais d&#8217;une structure de données constituée de champs. Un champ est une donnée possédant un nom (titre, auteur, date de publication, contenu, ..) et à laquelle est associé du texte. C&#8217;est ce texte qui est indexé, recherchable et affichable. Les documents indexés sont regroupés au sein d&#8217;une collection de documents appelée &laquo;&nbsp;index&nbsp;&raquo;. Un index peut contenir plusieurs centaines, milliers ou millions de documents et il est possible de créer autant d&#8217;index différents que le nécessite votre ou vos applications. Physiquement, un index est un répertoire (que vous spécifiez) hébergeant un nombre variable de fichiers (ça c&#8217;est l&#8217;affaire de Lucene).</p>
<p>Si le texte qui est à indexé est contenu dans des fichiers Excel, Word, PDF ou HTML, c&#8217;est de votre ressort d&#8217;en extraire de contenu textuel qui sera indexé. Il est possible d&#8217;utiliser par exemple <a href="http://www.foolabs.com/xpdf/download.html" target="_blank">pdftotext</a> pour les fichiers PDF, <a href="http://www.winfield.demon.nl/" target="_blank">Antiword</a> pour les fichiers Microsoft Word ou tout simplement <a href="http://lucene.apache.org/tika/" target="_blank">la boite à outils Tika</a> qui permet l&#8217;extraction du contenu d&#8217;un grand nombre de format de fichiers.</p>
<h3>Obtenir et utiliser Lucene</h3>
<p>La version actuelle de Lucene est la 2.9 et est disponible <a href="http://www.apache.org/dyn/closer.cgi/lucene/java/" target="_blank">ici</a>. La fichier lucene-x.x.x.zip est suffisant, mais le fichier lucene-x.x.x-src.zip avec les sources devient vite intéressant lorsque l&#8217;on veut étendre les possibilités de lucene et disposer d&#8217;exemples de code.</p>
<p>Dans la suite de cet article nous allons voir un exemple minimaliste illustrant comment indexer et rechercher des données. Cet exemple nous permet d&#8217;introduire les concepts de base de Lucene : document, field, analyzer, query, hits, &#8230;</p>
<p>La première chose à faire afin de pouvoir développer des classes Java utilisant Lucene, c&#8217;est de créer un projet dans votre environnement de développement et d&#8217;y inclure la librairie principale de Lucene : lucene-core-x.x.x.jar. J&#8217;utilise pour ma part <a href="http://www.eclipse.org/downloads/" target="_blank">Eclipse</a>. A noter qu&#8217;un bug dans Sun Java 1.6 a posé problème avec Lucene (<a href="http://www.nabble.com/Bug-in-Sun%27s-1.6-hotspot-compiler-that-can-cause-index-corruption-to18739358.html" target="_blank">détails ici</a>), ce bug a été corrigé à partir de la version 1.6.0_10-rc-b28.</p>
<h3>Un peu de pratique</h3>
<p>L&#8217;exemple qui suit est constitué d&#8217;une unique classe <strong>LuceneIntroduction.java</strong> dont voici le projet <strong>Eclipse</strong> complet dans un <a href="http://www.zoonix.fr/uploads/2008/08/1-Introduction.zip" target="_blank">fichier zip</a>.</p>
<h4>Squelette de la classe</h4>
<p>Le code suivant constitue le squelette de la classe. Il déclare les packages nécessaires et la méthode <strong>main</strong> qui exécute successivement une méthode pour l&#8217;indexation et une méthode pour la recherche.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.analysis.Analyzer</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.analysis.standard.StandardAnalyzer</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.document.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.index.IndexWriter</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.search.Query</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.search.Hits</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.search.Hit</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.queryParser.QueryParser</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.search.IndexSearcher</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.File</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.*</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LuceneIntroduction <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> INDEX_DIR <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;c:<span style="color: #000099; font-weight: bold;">\\</span>temp<span style="color: #000099; font-weight: bold;">\\</span>index_test&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #003399;">System</span>.<span style="color: #006633;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>searchAndDisplay<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;titi&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #003399;">System</span>.<span style="color: #006633;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>searchAndDisplay<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bla&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #003399;">System</span>.<span style="color: #006633;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h4>Indexer des données</h4>
<p>L&#8217;indexation de données met en oeuvre 4 classes Lucene.</p>
<table style="width: 100%; height: 40px;" border="0" align="left">
<tbody>
<tr valign="top">
<td><strong>IndexWriter</strong></td>
<td>c&#8217;est la classe qui donne accès aux index en écriture (création, ajout de document, optimisation, &#8230;)</td>
</tr>
<tr valign="top">
<td><strong>Analyzer</strong></td>
<td>
<p>il s&#8217;agit d&#8217;un ensemble de classes qui ont pour but le découpage du texte en &laquo;&nbsp;token&nbsp;&raquo; (mot) et la normalisation du texte à indexer. Les principaux analyzer fournis sont :</p>
<table style="width: 100%;" border="0" bgcolor="#eeeeee">
<tbody>
<tr>
<td valign="top">SimpleAnalyzer</td>
<td></td>
<td valign="top">SimpleAnalyzer découpe le texte en mot et le converti en minuscule.</td>
</tr>
<tr>
<td valign="top">StopAnalyzer</td>
<td></td>
<td valign="top">StopAnalyzer découpe le texte en mot, le converti en minuscule et supprime les mots vides (mots sans intérêt dans le processus de recherche : le, la, de &#8230;)</td>
</tr>
<tr>
<td valign="top">StandardAnalyzer</td>
<td></td>
<td valign="top">StandardAnalyzer combine les deux analyzer précédents</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr valign="top">
<td><strong>Document</strong></td>
<td>Un Document représente une unité élémentaire d&#8217;information. Par exemple, indexer tous les fichiers Word d&#8217;un répertoire va ajouter dans l&#8217;index un Document Lucene par fichier. Ce sont des Documents qui sont retournés dans la liste de résultats d&#8217;une recherche. Comme cela a déjà été dit, un document est constitué de champs &laquo;&nbsp;Field&nbsp;&raquo; (nom / valeurs).</td>
</tr>
<tr valign="top">
<td><strong>Field</strong></td>
<td>Il s&#8217;agit d&#8217;un sous élément d&#8217;un document. Les champs les plus fréquents sont : titre, auteur, date de publication, url et bien sur le texte du fichier Word, PDF ou HTML.</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>Le code suivant créer un index et ajoute 3 documents dans cet index. La méthode <strong>createDocument </strong>est plus particulièrement dédiée à la création d&#8217;un objet Document Lucene constitué de 3 champs : id, titre et texte.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> index <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #003399;">File</span> dir <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span> <span style="color: #009900;">&#40;</span>INDEX_DIR<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dir.<span style="color: #006633;">exists</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Impossible de créer l'index dans le répertoire '&quot;</span>
                       <span style="color: #339933;">+</span> INDEX_DIR
                       <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;', veuillez le supprimer d'abord.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>	
&nbsp;
  <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Création de l'index</span>
    IndexWriter writer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IndexWriter<span style="color: #009900;">&#40;</span>INDEX_DIR,
                                         <span style="color: #000000; font-weight: bold;">new</span> StandardAnalyzer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,
                                         <span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Création et indexation d'un premier document</span>
    <span style="color: #003399;">Document</span> doc <span style="color: #339933;">=</span> createDocument <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1&quot;</span>, <span style="color: #0000ff;">&quot;Titre 1&quot;</span>, <span style="color: #0000ff;">&quot;bla bla&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    writer.<span style="color: #006633;">addDocument</span><span style="color: #009900;">&#40;</span>doc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Création et indexation d'un second document</span>
    doc <span style="color: #339933;">=</span> createDocument <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;2&quot;</span>, <span style="color: #0000ff;">&quot;Titre 2&quot;</span>, <span style="color: #0000ff;">&quot;titi tutu&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    writer.<span style="color: #006633;">addDocument</span><span style="color: #009900;">&#40;</span>doc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Création et indexation d'un troisième document</span>
    doc <span style="color: #339933;">=</span> createDocument <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;3&quot;</span>, <span style="color: #0000ff;">&quot;Titre 3&quot;</span>, <span style="color: #0000ff;">&quot;bla bla titi tutu&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    writer.<span style="color: #006633;">addDocument</span><span style="color: #009900;">&#40;</span>doc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Fermeture de l'index</span>
    writer.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>	    
&nbsp;
  <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">Document</span> createDocument <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id, <span style="color: #003399;">String</span> titre,
                                        <span style="color: #003399;">String</span> texte<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Créer un document vide</span>
  <span style="color: #003399;">Document</span> doc <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Document</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Créer le champ id</span>
  doc.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Field</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span>, id,
                     <span style="color: #003399;">Field</span>.<span style="color: #006633;">Store</span>.<span style="color: #006633;">YES</span>, <span style="color: #003399;">Field</span>.<span style="color: #006633;">Index</span>.<span style="color: #006633;">UN_TOKENIZED</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Créer le champ titre</span>
  doc.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Field</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;titre&quot;</span>, titre,
                     <span style="color: #003399;">Field</span>.<span style="color: #006633;">Store</span>.<span style="color: #006633;">YES</span>, <span style="color: #003399;">Field</span>.<span style="color: #006633;">Index</span>.<span style="color: #006633;">TOKENIZED</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Créer le champ texte</span>
  doc.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Field</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;texte&quot;</span>, texte,
                     <span style="color: #003399;">Field</span>.<span style="color: #006633;">Store</span>.<span style="color: #006633;">NO</span>, <span style="color: #003399;">Field</span>.<span style="color: #006633;">Index</span>.<span style="color: #006633;">TOKENIZED</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">return</span> doc<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>On remarque que l&#8217;analyzer utilisé est spécifié au constructeur de l&#8217;objet IndexWriter. Et qu&#8217;un ensemble d&#8217;attributs importants sont spécifiés au constructeur de l&#8217;objet Field.</p>
<p>Le premier attribut est le mode de stockage de la donnée associée au champ : <em>Field.Store.YES</em> (stocké) ou <em>Field.Store.NO</em> (non stocké). Pour être indexé, une donnée ne doit pas forcément être stockée. On stockera un titre et un auteur par exemple car il doivent pouvoir être récupérés afin d&#8217;être affichés dans une liste de résultats. La totalité du texte d&#8217;un document PDF de 100 pages ne sera pas stocké mais juste indexé.</p>
<p>Le second attribut est le mode d&#8217;indexation de la donnée associée au champ : Field.Index.NO (non indexé), Field.Index.TOKENIZED (indexé avec découpage en mots), Field.Index.UN_TOKENIZED (indexé sans découpage en mots).</p>
<h4>Rechercher</h4>
<p>La recherche met en oeuvre 6 classes Lucene.</p>
<table style="width: 100%; height: 40px;" border="0" align="left">
<tbody>
<tr valign="top">
<td><strong>IndexSearcher</strong></td>
<td>c&#8217;est la classe qui donne accès aux index en recherche</td>
</tr>
<tr valign="top">
<td><strong>Analyzer</strong></td>
<td>
<p>Tout comme pour l&#8217;indexation les analyzer font partie du processus de recherche fin de normaliser les critères de recherche :</p>
</td>
</tr>
<tr valign="top">
<td><strong>QueryParser</strong></td>
<td>un parser de requête</td>
</tr>
<tr valign="top">
<td><strong>Query</strong></td>
<td>un objet qui représente la requête de l&#8217;utilisateur et utilisé par un IndexSearcher.</td>
</tr>
<tr>
<td><strong>Hits</strong></td>
<td>Une collection d&#8217;éléments résultats de la recherche</td>
</tr>
<tr>
<td><strong>Hit</strong></td>
<td>Un élément de la collection des résultats</td>
</tr>
<tr>
<td><strong>Document</strong></td>
<td>Un document retrouvé et tel qu&#8217;il était lors de son ajout dans l&#8217;index (constitué des mêmes champs)</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>Le code suivant recherche les documents correspondant au critère et les affiche.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> searchAndDisplay <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> criteria<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    IndexSearcher searcher <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IndexSearcher<span style="color: #009900;">&#40;</span>INDEX_DIR<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    QueryParser parser <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> QueryParser<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;texte&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> StandardAnalyzer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Query query <span style="color: #339933;">=</span> parser.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>criteria<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Hits hits <span style="color: #339933;">=</span> searcher.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>query<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Résultats pour '&quot;</span> <span style="color: #339933;">+</span> criteria <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;': &quot;</span> <span style="color: #339933;">+</span> hits.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Iterator</span> iter <span style="color: #339933;">=</span> hits.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>iter.<span style="color: #006633;">hasNext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      Hit hit <span style="color: #339933;">=</span> iter.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #003399;">Document</span> doc <span style="color: #339933;">=</span> hit.<span style="color: #006633;">getDocument</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>doc.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;titre&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>	    	    
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h4>Résultat de l&#8217;exécution</h4>
<pre>Résultats pour 'titi': 2
Titre 2
Titre 3
Résultats pour 'bla': 2
Titre 1
Titre 3
</pre>
<h3>Et si mes applications ne sont pas écrites en Java ?</h3>
<p>Si vous acceptez de ne pas utiliser la toute dernière version de Lucene, vous pouvez utiliser une version portée dans votre langage de programmation préféré. Il existe de nombreux portages : <a href="http://search.cpan.org/dist/Plucene/" target="_blank">Perl</a>, <a href="http://pylucene.osafoundation.org/" target="_blank">Python</a>, <a href="http://fr.wikipedia.org/wiki/Ferret_%28moteur_de_recherche%29" target="_blank">Ruby</a>, <a href="http://incubator.apache.org/lucene4c/" target="_blank">C</a>, <a href="http://sourceforge.net/projects/clucene/" target="_blank">C++</a>, <a href="http://incubator.apache.org/lucene.net/" target="_blank">.NET</a>, <a href="http://projects.heavymeta.org/montezuma/" target="_blank">Common Lisp</a> et <a href="http://framework.zend.com/" target="_blank">PHP</a> (recherche uniquement).</p>
<p>Si comme moi vous préférez utiliser la version originale Java en permanente évolution grâce à sa grande communauté de développeurs, voici ma suggestion : les <a href="http://fr.wikipedia.org/wiki/Web_services" target="_blank">Services Web</a>.</p>
<p>Vous avez écrit une application Web dont l&#8217;interface est en PHP et les données sont dans une base SQL. Vous n&#8217;avez pas le choix, il faut développer votre moteur de recherche avec Java. Par contre, il faut également interfacer ce moteur de recherche avec votre application PHP pour lancer les recherches et afficher les résultats.</p>
<p>Pour la partie indexation des données il n&#8217;est pas nécessaire de s&#8217;interfacer avec le PHP, une application Java autonome peut être développée. Par contre, pour la recherche il faut interfacer le code PHP avec le code Java. La solution consiste en la mise en place de <strong>Services Web</strong> écrits en Java et fonctionnants sous <strong>Tomcat</strong>. Il n&#8217;est pas nécessaire de se lancer dans des <strong>Services Web</strong> au standard <a href="http://fr.wikipedia.org/wiki/Web_services#Les_Services_Web_WS" target="_blank">SOAP</a>, le standard <a href="http://fr.wikipedia.org/wiki/Web_services#Les_Services_Web_de_type_REST" target="_blank">REST</a> est largement suffisant. En gros une requête HTTP est envoyée à une servlet qui elle même retourne des résultats au format XML. Cette méthode permet d&#8217;interfacer la recherche Java/Lucene à tous types d&#8217;applications (WEB ou non WEB) et écrites dans n&#8217; importe quel langage.</p>
<h3>Extensions de Lucene</h3>
<p>L&#8217;exemple présenté est comme je l&#8217;ai déjà dit &laquo;&nbsp;minimaliste&nbsp;&raquo;. Les possibilités offertes par Lucene sont très larges et se rapprochent des moteurs de recherche les plus puissants. En effet, il existe de nombreuses extensions fournies dans la distribution : analyzers avancées, corrections orthographiques, mise en évidence des termes recherchés dans les résultats, &#8230;</p>
<p>En voici la présentation dans la <a href="http://lucene.apache.org/java/docs/lucene-sandbox/index.html" target="_blank">Sandbox Lucene</a></p>
<h3>Utilitaires</h3>
<p>Voici deux utilitaires intéressants en phase de développement.</p>
<p><a href="http://www.getopt.org/luke/" target="_blank">Luke</a> &#8211; outils de monitoring et de consultation des index</p>
<p><a href="http://limo.sourceforge.net/" target="_blank">Limo</a> &#8211; outils de monitoring des index</p>
<h3>Documentation</h3>
<p>La documentation est disponible <a href="http://lucene.apache.org/java/docs/index.html" target="_blank">ici</a>. En plus de la javadoc, on y trouve une FAQ, un Wiki et différents articles intéressants.</p>
<p>jGuru fournit une <a href="http://www.jguru.com/faq/Lucene" target="_blank">FAQ Lucene</a> intéressante.</p>
<p>Et enfin, il existe un livre en anglais basé sur une déjà ancienne version 1.4 : <a href="http://www.eyrolles.com/Informatique/Livre/9781932394283/livre-lucene-in-action.php" target="_blank">Lucene in Action</a> (2004). La second édition du livre doit être disponible prochainement.</p>
<h3>Support et assistance</h3>
<p>Lucene est un projet open source, il n&#8217;existe pas de support à proprement parlé, mais il existe une <a href="http://lucene.apache.org/java/docs/mailinglists.html" target="_blank">mailing-list</a> et un <a href="http://www.nabble.com/Lucene-f44.html" target="_blank">forum</a> très actifs qui permettent d&#8217;obtenir de l&#8217;aide et des suggestions pour les problèmes les plus pointus.</p>
<h3>Projets utilisant Lucene</h3>
<p><a href="http://lucene.apache.org/solr/" target="_blank">Solr </a></p>
<p><a href="http://www.cdlib.org/inside/projects/xtf/" target="_blank">eXtensible Text Framework (XTF)</a></p>
<p><a href="http://www.hibernate.org/410.html" target="_blank">Hibernate Search</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2009/10/01/introduction-a-lucene/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les moteurs de recherche</title>
		<link>http://www.wiizio.com/2009/10/01/les-moteurs-de-recherche/</link>
		<comments>http://www.wiizio.com/2009/10/01/les-moteurs-de-recherche/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 19:54:46 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false">http://www.wiizio.com/?p=73</guid>
		<description><![CDATA[<p>Pour la plupart des internautes, &#171;&#160;moteur de recherche&#160;&#187; est synonyme de Google ou Yahoo. En fait, je les appellerais plutôt &#171;&#160;sites de recherche&#160;&#187;. Un moteur de recherche est en fait un outil ou ensemble d&#8217;outils permettant de construire par exemple ces &#171;&#160;sites de recherche&#160;&#187;, mais également d&#8217;ajouter des fonctionnalités de recherche à divers types d&#8217;applications <p>Lire la suite <a href="http://www.wiizio.com/2009/10/01/les-moteurs-de-recherche/">Les moteurs de recherche</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2008/08/search.jpg"><img class="alignleft size-medium wp-image-54" title="search" src="http://www.zoonix.fr/uploads/2008/08/search.jpg" alt="" width="72" height="91" /></a>Pour la plupart des internautes, <strong>&laquo;&nbsp;moteur de recherche&nbsp;&raquo;</strong> est synonyme de <strong>Google </strong>ou <strong>Yahoo</strong>. En fait, je les appellerais plutôt <strong>&laquo;&nbsp;sites de recherche&nbsp;&raquo;</strong>. Un moteur de recherche est en fait un outil ou ensemble d&#8217;outils permettant de construire par exemple ces &laquo;&nbsp;sites de recherche&nbsp;&raquo;, mais également d&#8217;ajouter des fonctionnalités de recherche à divers types d&#8217;applications (CRM, messagerie, &#8230;).</p>
<p>Avant de pouvoir offrir une page de recherche et des résultats, il est nécessaire de réaliser certaines tâches comme par exemple la création d&#8217;un index des données. <span id="more-73"></span>En simplifiant, les étapes de la mise en place d&#8217;une solution de recherche sont :</p>
<ul>
<li>accéder aux données à indexer : système de fichiers, sites web (<a href="http://fr.wikipedia.org/wiki/Robot_d%27indexation" target="_blank">crawler</a>), base de données, messagerie, &#8230; </li>
<li>parser les données à indexer afin d&#8217;en extraire le texte, diverses propriétés (titre, auteur, date de publication, &#8230; ) et pour un site web les liens vers d&#8217;autres pages </li>
<li>supporter différents jeux de caractères et différentes langues (et éventuellement être capable de <a href="http://www.zoonix.fr/2008/02/20/detection-de-la-langue-dun-texte/">détecter la langue du document</a>) </li>
<li>créer l&#8217;index proprement dit qui est la plus part du temps constitué d&#8217;un ensemble de fichiers et de structures de données de type B-trees. </li>
<li>paramétrer la solution au moyen de listes de mots vides, de dictionnaire de synonymes, de thésaurus, &#8230; </li>
<li>Mettre en place la sécurité : authentification et droits d’accès</li>
<li>administrer la solution au moyen d&#8217;outils de manipulation des index (création, suppression, optimisation, sauvegarde, réindexation, &#8230;) </li>
<li>créer une interface de recherche Web ou embarquée dans une application non Web </li>
<li>mettre en place des fonctionnalités facilitant l’accès à la bonne information : alertes, filtres, entités nommées</li>
</ul>
<p>Lors de l&#8217;apparition des premières solutions commerciales à la fin des années 80 (avec <a href="http://en.wikipedia.org/wiki/BRS/Search" target="_blank">BRS/Search</a> ou <a href="http://en.wikipedia.org/wiki/Lotus_Magellan" target="_blank">Lotus magellan</a> par exemple), les moteurs de recherche permettent d&#8217;indexer uniquement des fichiers de format simple (texte) localisés dans un système de fichiers. Avec le temps, ils ont appris à accéder à des sources d&#8217;informations variées, à traiter un très grand nombre de formats de fichiers, à tenir compte des droits d&#8217;accès aux données et bien d&#8217;autres choses encore.</p>
<p>Les moteurs de recherches sont très connus au travers des solutions WEB telles que <strong>Google </strong>ou <strong>Yahoo </strong>mais ils sont également présents dans des outils d&#8217;entreprise (Gestion de contenu, CRM, Gestion documentaire, Outils de veille) et des outils grands publics tel que la messagerie ou le &laquo;&nbsp;<a href="http://en.wikipedia.org/wiki/Desktop_search" target="_blank">Desktop search</a>&nbsp;&raquo; (Google Desktop, Copernic, &#8230;).</p>
<h3>Fonctionnement d&#8217;un moteur de recherche</h3>
<h4>L&#8217;index</h4>
<p>La brique de base d&#8217;un moteur de recherche c&#8217;est l&#8217;index. Il s&#8217;agit d&#8217;une structure de données organisée afin de permettre au moteur de retrouver très rapidement les documents correspondants a une requête de l&#8217;utilisateur. Il s&#8217;agit dans la plupart des cas d&#8217;un ensemble de fichiers. Ces fichiers ont pour rôle de mémoriser l&#8217;emplacement de <strong>TOUS LES MOTS</strong> présents dans l&#8217;ensemble des données indexées (soit plusieurs milliers à plusieurs millions d&#8217;occurrences de mots). Un index ne contient pas une entrée par document avec la liste des mots du document, mais il contient une entrée par mot avec la liste des documents ou se trouve ce mot <strong>ET</strong> pour chaque occurrence d&#8217;un mot, sa position exacte dans les documents.</p>
<p>Imaginons par exemple un tous petit corpus de 4 documents contenant seulement une phrase chacun.</p>
<table style="width: 100%;" border="0" bgcolor="#eeeeee">
<tbody>
<tr>
<td width="25%" valign="top">Document 1 (doc1)</td>
<td width="5"></td>
<td valign="top">&laquo;&nbsp;L&#8217;avocat que je mange est bien vert.&nbsp;&raquo;</td>
</tr>
<tr>
<td valign="top">Document 2 (doc2)</td>
<td></td>
<td valign="top">&laquo;&nbsp;Je suis tombé sur un avocat pourri.&nbsp;&raquo;</td>
</tr>
<tr>
<td valign="top">Document 3 (doc3)</td>
<td></td>
<td valign="top">&laquo;&nbsp;Je suis vert car mon avocat m&#8217;a conseillé de plaider coupable.&nbsp;&raquo;</td>
</tr>
<tr>
<td>Document 4 (doc4)</td>
<td></td>
<td>&laquo;&nbsp;Un avocat coupable de malversations.&nbsp;&raquo;</td>
</tr>
</tbody>
</table>
<p>On constate que certains mots sont présents plusieurs fois. En considérant les mots &laquo;&nbsp;l&nbsp;&raquo;, &laquo;&nbsp;que&nbsp;&raquo;, &laquo;&nbsp;je&nbsp;&raquo;, &laquo;&nbsp;est&nbsp;&raquo;, &laquo;&nbsp;bien&nbsp;&raquo;, &laquo;&nbsp;suis&nbsp;&raquo;, &laquo;&nbsp;sur&nbsp;&raquo;, &laquo;&nbsp;mon&nbsp;&raquo;, &laquo;&nbsp;m&nbsp;&raquo;, &laquo;&nbsp;a&nbsp;&raquo; et &laquo;&nbsp;de&nbsp;&raquo; comme vides, et en utilisant la notation &laquo;&nbsp;identifiant document / position&nbsp;&raquo; pour décrire les positions des mots, ceci donnerait dans l&#8217;index :</p>
<table style="width: 100%;" border="0" bgcolor="#eeeeee">
<tbody>
<tr>
<td width="25%" valign="top">avocat</td>
<td width="5"></td>
<td valign="top">doc1/1, doc2/2, doc3/3, doc4/1</td>
</tr>
<tr>
<td valign="top">car</td>
<td></td>
<td valign="top">doc3/2</td>
</tr>
<tr>
<td valign="top">conseillé</td>
<td></td>
<td valign="top">doc3/4</td>
</tr>
<tr>
<td>coupable</td>
<td></td>
<td>doc3/6, doc4/2</td>
</tr>
<tr>
<td>malversations</td>
<td></td>
<td>doc4/3</td>
</tr>
<tr>
<td>mange</td>
<td></td>
<td>doc1/2</td>
</tr>
<tr>
<td>plaider</td>
<td></td>
<td>doc3/5</td>
</tr>
<tr>
<td>pourri</td>
<td></td>
<td>doc2/3</td>
</tr>
<tr>
<td>tombé</td>
<td></td>
<td>doc2/1</td>
</tr>
<tr>
<td>vert</td>
<td></td>
<td>doc1/3, doc3/1</td>
</tr>
</tbody>
</table>
<p>On constate tout d&#8217;abord que l&#8217;utilisation de mots vides permet de réduire considérablement la taille d&#8217;un index et donc d&#8217;optimiser les temps d&#8217;indexation puis de recherche. On comprend également que lorsque le nombre de documents va augmenter, le nombre de mots nouveaux va avoir tendance à se stabiliser car les mots des documents ajoutés seront souvent déjà présents dans l&#8217;index. La taille de l&#8217;index va croître moins vite car pour les mots déjà présents dans l&#8217;index, seules la référence des documents et la position des mots sont à ajouter au fichier d&#8217;index.</p>
<p>Dans un index, les mots ne sont pas classés alphabétiquement comme dans mon exemple, mais placés dans une structure de données de type <a href="http://fr.wikipedia.org/wiki/Arbre_B" target="_blank">B-Tree</a>. Ajouter, trouver et supprimer un élément dans une telle structure est infiniment plus rapide que dans une liste ordonnée.</p>
<p>Un moteur de recherche peut gérer simultanément plusieurs index (pour des données distinctes d&#8217;une même application, pour des applications différentes d&#8217;une même société, pour séparer des données dans des langues différentes, &#8230;).</p>
<h4>Les requêtes</h4>
<p>Fort de cet index, le moteur de recherche est à même de répondre aux requêtes des utilisateurs. Il existe deux types de requête : les requêtes booléennes et les requêtes en &laquo;&nbsp;langage naturel&nbsp;&raquo;.</p>
<p><span style="text-decoration: underline;">Les requêtes booléennes</span> ont toujours existé dans les moteurs de recherche. Elles permettent de décrire les documents désirés au moyen d&#8217;opérateurs tels que : ET, OU, SAUF, PROCHE, PHRASE EXACTE, TRONCATURE, &#8230;</p>
<p>Voici quelques exemples de requêtes et de résultats basés sur notre index</p>
<table style="width: 100%;" border="0" bgcolor="#eeeeee">
<tbody>
<tr>
<td width="50%" valign="top">avocat</td>
<td width="5"></td>
<td valign="top">doc1, doc2, doc3 et doc4</td>
</tr>
<tr>
<td valign="top">avocat <strong>ET </strong>vert</td>
<td></td>
<td valign="top">doc1 et doc3</td>
</tr>
<tr>
<td valign="top">avocat <strong>SAUF </strong>vert</td>
<td></td>
<td valign="top">doc2 et doc4</td>
</tr>
<tr>
<td>avocat <strong>ET </strong>pourri</td>
<td></td>
<td>doc2</td>
</tr>
<tr>
<td>avocat <strong>OU </strong>pourri</td>
<td></td>
<td>doc1, doc2, doc3 et doc4</td>
</tr>
<tr>
<td>avocat <strong>ET </strong>coupable</td>
<td></td>
<td>doc3 et doc4</td>
</tr>
<tr>
<td><strong>&laquo;&nbsp;</strong>avocat coupable<strong>&laquo;&nbsp;</strong></td>
<td></td>
<td>doc4</td>
</tr>
<tr>
<td>avocat <strong>PROCHE 2 MOTS</strong> coupable</td>
<td></td>
<td>doc4</td>
</tr>
<tr>
<td>p<strong>*</strong></td>
<td></td>
<td>doc2 et doc3</td>
</tr>
</tbody>
</table>
<p>Ce type de requête utilise uniquement des éléments statistiques fournis par l&#8217;index : présence, position et occurrences des mots. Le gros inconvénient de ce type de requête est la nécessitée pour l&#8217;utilisateur de connaître la syntaxe booléenne propre à l&#8217;outil utilisé ou pour les concepteurs de fournir des écrans de recherche complexes guidant l&#8217;utilisateur (comme par exemple <a href="http://www.google.fr/advanced_search?hl=fr" target="_blank">la recherche avancée de Google</a>)</p>
<p><span style="text-decoration: underline;">Les requêtes en langage naturel</span> sont apparues plus tard. Le premier but est de permettre à l&#8217;utilisateur d&#8217;interroger le système à l&#8217;aide d&#8217;expressions ou de phrases plus ou moins précises mais surtout de ne pas être obliger l&#8217;utilisateur à connaître une syntaxe booléenne complexe et rébarbative.</p>
<p>Par exemple, l&#8217;utilisateur qui s&#8217;intéresse à la dégustation des avocats saisit la requête &laquo;&nbsp;Comment déguster un avocat ?&nbsp;&raquo;. Bien que &laquo;&nbsp;comment&nbsp;&raquo; et &laquo;&nbsp;déguster&nbsp;&raquo; ne soient présents dans aucun document, le moteur va sans doute trouver des résultats. En effet, les moteurs retirent les mots vides de la question et aussi les mots ou expressions typiques d&#8217;une question : &laquo;&nbsp;comment&nbsp;&raquo;, &laquo;&nbsp;pourquoi&nbsp;&raquo;, &laquo;&nbsp;je cherche &#8230;&nbsp;&raquo;. Exit donc le mot &laquo;&nbsp;comment&nbsp;&raquo;. Ensuite, si aucun document ne correspond exactement, le moteur doit fournir les documents les plus proches possible de la requête et doit utiliser tous les mots de la requête pour orienter le résultat. Dans cet exemple, &laquo;&nbsp;déguster&nbsp;&raquo; doit orienter vers un avocat qui se mange et donc retourner les documents 1 et 2. Bien sur cela impose un index plus complexe qui contienne une information complémentaire sur la nature des avocats. Ce qui donne par exemple l&#8217;index suivant :</p>
<table style="width: 100%;" border="0" bgcolor="#eeeeee">
<tbody>
<tr>
<td width="25%" valign="top">avocat (fruit)</td>
<td width="5"></td>
<td valign="top">doc1/1</td>
</tr>
<tr>
<td valign="top">avocat (métier)</td>
<td></td>
<td valign="top">doc3/3, doc4/1</td>
</tr>
<tr>
<td valign="top">avocat (indéterminé)</td>
<td></td>
<td valign="top">doc2/2</td>
</tr>
</tbody>
</table>
<p>Pour ce type de requête, le moteur utilise les éléments statistiques de l&#8217;index, mais également des informations sémantiques (sens des mots), morphologiques (forme des mots) et syntaxique (mots composés et expressions) après <a href="http://fr.wikipedia.org/wiki/Analyse_s%C3%A9mantique" target="_blank">analyse du texte</a> indexé et de la requête.</p>
<h4>Pertinence des résultats</h4>
<p>Une fois obtenue la liste des documents correspondants à une requête, ce que l&#8217;on demande à un moteur est de nous fournir les <a href="http://fr.wikipedia.org/wiki/Page_de_r%C3%A9sultats_d%27un_moteur_de_recherche" target="_blank">résultats</a> classés par &laquo;&nbsp;pertinence&nbsp;&raquo;. Il s&#8217;agit de retourner en premier les documents qui répondent le mieux à la requête et là encore, le moteur s&#8217;appuie sur son index pour calculer la pertinence. Selon les moteurs, il existe plusieurs algorithmes de calcul de pertinence. Par exemple, l&#8217;algorithme qui privilégie les documents qui contiennent le plus de mots de la requête. Dans ce cas, pour la requête &laquo;&nbsp;avocat OU pourri&nbsp;&raquo;, le moteur va retourner le document 2 en premier.</p>
<p>Deux autres indicateurs majeurs de pertinence sont la proximité et le bon ordonnacement des mots de la requête dans le document.</p>
<p>Les algorithmes peuvent être très variés. Par exemple, le très célèbre &laquo;&nbsp;<a href="http://fr.wikipedia.org/wiki/PageRank" target="_blank">Page Rank</a>&nbsp;&raquo; de Google n&#8217;est pas basé que sur la fréquence d&#8217;apparition des mots recherchés au sein des documents trouvés, mais grandement sur la popularité du site hébergeant le document en tenant compte du nombre des autres sites pointant sur lui.</p>
<p>Certains moteurs savent également, par des algorithmes d’analyse grammaticale dépendants de la langue, déterminer si l’expression recherchée (dégustation d’avocat, par exemple) est un sujet central dans le document ou bien traitée en aparté. Dans le premier cas, le document sera considéré comme plus pertinent.</p>
<h4>Les propriété associées aux documents (metadonnées)</h4>
<p>Aux documents indexés sont généralement associées un minimum de métadonnées : titre, auteur, mots-clés, date de publication, &#8230;. Ces métadonnées sont gérées dans une application métier (messagerie, CRM) et saisies par des utilisateurs. Une partie d&#8217;entre elles sont indexées par le moteur et donc elles peuvent être utilisées comme critère de recherche ou de tri des résultats (par exemple, pour rechercher tous les documents sur les avocats et publiés après une certaine date) et affichées dans la liste de résultats.</p>
<p>Il existe par exemple un schéma de metadonnées normalisé (<a href="http://fr.wikipedia.org/wiki/ISO_15836" target="_blank">ISO 15836</a>) appelé <a href="http://fr.wikipedia.org/wiki/Dublin_Core" target="_blank">Dublin Core</a>. Le <strong>Dublin Core</strong> permet de décrire des ressources numériques ou physiques et d’établir des relations avec d&#8217;autres ressources. Il comprend officiellement 15 éléments de description formels (titre, créateur, éditeur), intellectuels (sujet, description, langue, …) et relatifs à la propriété intellectuelle.</p>
<h3>Faut-il choisir un moteur &laquo;&nbsp;statistique&nbsp;&raquo; ou &laquo;&nbsp;sémantique&nbsp;&raquo; ?</h3>
<p>Comme cela a été dit précédemment, tous les moteurs sont statistiques à la base. La question doit donc être &laquo;&nbsp;Faut-il choisir un moteur avec des fonctionnalités sémantiques ?&nbsp;&raquo;. Plusieurs paramètres sont à prendre en considération afin de répondre à cette question.</p>
<h4>Quelle est la nature des données (spécifique à un métier, généraliste) ?</h4>
<p>Les moteurs sémantiques mettent en oeuvre des algorithmes d&#8217;analyse du texte qui nécessitent des dictionnaires. Le rôle de ces dictionnaires est de fournir des informations sur les mots : nature (nom, adjectif), synonymes, &#8230;. Si le ou les domaines couverts par les documents indexés sont multiples, vastes et évolutifs, ces dictionnaires seront plus longs (donc coûteux) à élaborer et à maintenir.</p>
<p>Les moteurs sémantiques sont donc plus adaptés à des moteurs spécialisés qu&#8217;à des moteurs généralistes. Il est toutefois possible de mettre en oeuvre une &laquo;&nbsp;couche sémantique&nbsp;&raquo; généraliste et légères qui ne demande pas trop de maintenance des dictionnaires. Mais, avec une couche sémantique légère, il ne faudra pas attendre de miracles avec des applications métiers (domaine médical, scientifique ou financier par exemple).</p>
<h4>Quel est le volume des données ?</h4>
<p>Sans doute pas le paramètre le plus important, mais il faut savoir que les étapes d&#8217;analyse sémantique des documents en phase d&#8217;indexation entraînent des temps de traitement plus long. C&#8217;est à prendre en compte donc si les temps d&#8217;indexation sont critiques et/ou les documents très nombreux.</p>
<h4>Quel type de population va utiliser le moteur de recherche ?</h4>
<p>Il faut savoir que les moteurs généralistes traitent 80% de requêtes constituées d&#8217;un seul mot. Contrairement à la requête &laquo;&nbsp;Comment déguster un avocat ?&nbsp;&raquo;, la requête &laquo;&nbsp;avocat&nbsp;&raquo; ne fournira pas d&#8217;information sur la nature de l&#8217;avocat recherché. Ces requêtes sont par défaut de type booléen et la couche sémantique du moteur n&#8217;est dans ce cas d&#8217;aucune utilité.</p>
<p>Sur des sites spécialisés utilisés par des spécialistes, les requêtes seront globalement plus précises et là, la couche sémantique donnera sa pleine puissance.</p>
<h4>Quel investissement matériel, logiciel et humain peut être alloué au projet ?</h4>
<p>Bien sur, il faut tenir compte des coups de licences et de matériels imposés par la solution évaluée, mais il faut surtout bien évaluer les ressources humaines nécessaires à la mise en oeuvre de la solution. Un moteur sémantique nécessite souvent un travail important en amont du projet pour constituer ou enrichir les dictionnaires. En phase d&#8217;exploitation, il est aussi nécessaire de bien suivre l&#8217;utilisation faite du moteur afin de déterminer les ajustements à apporter dans les dictionnaires (quelles requêtes sont posées, quelles requêtes ne remontent pas de documents et pourquoi, &#8230;).</p>
<h4>Quel est l&#8217;impact sur l&#8217;interface utilisateur et sa complexité d&#8217;utilisation ?</h4>
<p>Plus haut je disais qu&#8217;un moteur sémantique permet de mettre en place une interface plus simple. C&#8217;est vrai pour la zone de saisie de la requête, mais d&#8217;autres éléments peuvent venir s&#8217;ajouter à la liste de résultats :</p>
<ul>
<li>des navigateurs (liste d&#8217;auteurs, liste de thèmes, listes de lieux) qui vont permettre à l&#8217;utilisateur d&#8217;affiner sa requête. Les données affichées par ces navigateurs sont relatives aux documents trouvés et peuvent soit provenir des métadonnées, soit avoir fait l&#8217;objet d&#8217;une détection par le moteur dans le flux textuel des documents. Cette détection d’entités nommées est automatique (par calcul statistique) et/ou basée sur des dictionnaires. </li>
<li>une liste de questions proches et suggérées par le moteur. </li>
</ul>
<p>A prioris, ces fonctions sont des plus, mais elles complexifient l&#8217;interface.</p>
<h3>Choix et mise en oeuvre d&#8217;une solution</h3>
<p>La mise en place d&#8217;une solution de recherche se fait en deux temps : la recherche et la sélection d&#8217;un moteur, puis sa mise en oeuvre. La seconde phase sera bien sur plus simple, plus rapide et avec moins de surprises si la première phase a été bien menée.</p>
<p>Le choix d&#8217;une solution passe par l&#8217;écriture d&#8217;un cahier des charges, la rencontre des éditeurs et après une première sélection la réalisation de un ou deux prototypes pour valider les fonctionnalités critiques.</p>
<p>En phase de définition et de validation du prototype, une personne connaissant parfaitement le corpus de données et le métier doit être impliquée. De même plus tard en phase d&#8217;exploitation de la solution cette personne aura pour rôle d&#8217;évaluer régulièrement le bon fonctionnement du système : documents trouvés à tort (bruit), documents non trouvés et requêtes sans réponse (silence), pertinence des réponses.</p>
<p>Dès la phase d&#8217;élaboration du cahier des charges, il est souhaitable de se faire assister pas des spécialistes des solutions de recherche. Cette phase a également la vertu d&#8217;être pédagogique et donc permet de mieux conduire la sélection et la mise en oeuvre future.</p>
<p>Quelques paramètres à prendre en compte dans le choix d&#8217;une solution :</p>
<ul>
<li>fonctionnalités </li>
<li>langages supportés </li>
<li>volumétrie acceptée </li>
<li>performance en indexation et en recherche (coût de la couche sémantique) </li>
<li>ergonomie de l&#8217;interface de recherche </li>
<li>pertinence des résultats </li>
<li>ouverture de la solution (API) et extensions possibles (connexion à une source de données spécifique) </li>
<li>gestion de la sécurité et confidentialité des données</li>
<li>architecture préconisée (nombre de serveurs, mémoire, processeurs, espace disque), système d&#8217;exploitation, gestion de la monté en charge et autres pre-requis (matériels et logiciels) </li>
<li>administration et paramétrage du produit (charge de travail devant être en adéquation aux ressources disponibles en phase d&#8217;exploitation) </li>
<li>compétences à acquérir </li>
</ul>
<h3>Sites spécialisés dans les outils de recherche</h3>
<p>Je n&#8217;ai pas trouvé de site Français vraiment pertinent sur le sujet, je vous suggère donc uniquement <a href="http://www.searchtools.com/" target="_blank">Searchtools.com</a> (anglais). Un classique, mais les fiches produits ne sont pas toujours à jour (et oui ça bouge beaucoup). Il est accompagné d&#8217;un <a href="http://searchtools.livejournal.com/" target="_blank">blog</a> actif.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiizio.com/2009/10/01/les-moteurs-de-recherche/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

