First Tutorials SolR / Lucene / PDF old documents / database sample php
Administrating Solr Tika in Action Apache Solr 4 Cookbook Apache Solr High Performance
LIWP_SolrSearchforDatabaseProgrammers tutorial
Lucid Imagination_ECommerce-WP
Prévoir le module de connection mysq/jdbc pour les DIH :
Solr schema construction
http://leblogdundsi.lesprost.fr/article34/moteur-de-recherche-solr-sous-windows-tomcat
SolR est un moteur de recherche Open Source basé sur Lucene qui permet d’indexer tous types de documents (bases de données, fichiers,…) et d’exécuter des requêtes dessus. Il est très puissant et nous l’avons mis en place sur un site de petites annonces.
Nous allons détailler dans cet article comment l’installer sous Windows avec le serveur Tomcat et comment le remplir puis l’interroger.
::TOC::
Installation initiale
Prérequis
- Une JRE (ici, version 6 update 18)
Attention, sur www.java.com, la version par défaut est 32bits, pensez à bien choisir la version 64 bits i le serveur est en 64 bits.
Installation de Tomcat
- Installez Tomcat à partir du fichier exécutable d’install (32-bit/64-bit Windows Service Installer).
- Définissez un login (administrateur, par ex) et un mot de passe pour le manager.
- Lancez Tomcat puis arrêtez-le (ceci permet de créer les dossiers Catalina\localhost dans le dossier conf).
- Vérifiez dans le Gestionnaire de services que le service se lance bien automatiquement avec Windows (il est par défaut en démarrage manuel).
Préparation de SOLR
- Téléchargez la dernière version de Solr (ici, 1.4.0) au format zip sur http://www.apache.org/dyn/closer.cgi/lucene/solr/
- Dézipper la version binaire de SOLR dans C:\apache-solr-1.4.0 (on trouve dans ce dossier les dossiers client, contrib, examples, ) => Appelons ce dossier <src>.
- Créez un dossier C:\solr . Appelons ce dossier <home>
- Copier le dossier <src>/examples/webapps dans <home> (le dossier webapps contient le fichier solr.war)
- Créer dans <home> un dossier par index (ex : index1, index2)
- Copier dans chacun d’eux le contenu du dossier <src>/examples/solr/(dossiers bin et conf)
- Créer dans chacun d’eux un dossier data
Références
- http://www.eolya.fr/2008/12/08/introduction-a-solr-installation-et-configuration-1/
- http://www.eolya.fr/2009/05/10/introduction-a-solr-installation-et-configuration-2/
- http://drupal.org/node/532584
Configuration de TomCat
Chemin vers SOLR dans les paramètres de Tomcat
- Dans le manager TomCat (menu Démarrer => Configure Tomcat ou C:\Program Files\Apache Software Foundation\Tomcat 6.0\bin\ tomcat6w.exe) allez dans l’onglet Java.
- Ajoutez à la fin des Java options la ligne suivante :
-Dsolr.solr.home=<home>
(sans le \ final).
Fichiers de conf iguration Tomcat
- Editer le fichier C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\server.xml :
Ajouter URIEncoding=”UTF-8″ au noeud <Connector port=”8080″ protocol=”HTTP/1.1″… qui doit désormais ressembler à ceci :<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
- Dans C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\Catalina\localhost , créez un fichier solr.xml avec le contenu suivant :
<Context docBase="<home> \webapps\solr.war" debug="0" crossContext="true" > <Environment name="solr/home" type="java.lang.String" value="<home>\" override="true" /> </Context>
Fichier de configuration SOLR
Dans <home>, créer le fichier solr.xml avec le contenu suivant :
<solr persistent="true" sharedLib="lib"> <cores adminPath="/admin/cores"> <core name="index1" instanceDir="index1" /> <!--<core name="index2" instanceDir="index2"/>--> </cores> </solr>
Ce fichier permet de configurer les curs d’exécution de chaque index SolR.
Pour ce faire, il suffit d’ajouter une ligne <core name=””
pour chaque index.
- core name : nom du cur
- core instance : nom du dossier correspondant dans <home>
Tests
- Redémarrez Tomcat
- Lancez l’url suivante pour vérifier que tout est ok :
http://localhost:8080/solr/index1/admin/
- Normalement, les cores apparaissent dans la ligne Cores (si il y en a plusieurs de définis)
- En cas de problème, consultez les logs de Tomcat dans C:\Program Files\Apache Software Foundation\Tomcat 6.0\logs
Configuration de SolR
A faire pour chaque index. les fichiers de configuration se trouve dans <home>\<index>\conf
schema.xml
Le fichier schema.xml permet de paramétrer les champs à indexer (dans le nud fields) et les types de champ ainsi que le paramétrage de leur fonctionnement d’indexation (dans le noeud types).
Je vous renvoie à la documentation pour plus de détail mais voici quelques conseils:
- On ne peut indexer que des champs de type solr.TextField.
- Pour chaque champ, on peut indiquer si il est indexé (indexed=”true”) et/ou si il est stocké tel quel (stored=”true”).
Dans notre cas, nous avons défini plusieurs champs :
Nom | Utilisation | Type | Indexé | Stocké |
---|---|---|---|---|
monID | Clé unique | solr.TrieLongField | oui | oui |
monTexte | Bloc de texte qui sera affiché dans les recherches | solr.TextField | non | oui |
champ1 | Bloc servant pour les recherches (priorité élevée) | solr.TextField | oui | non |
champ2 | Bloc servant pour les recherches (priorité basse) | solr.TextField | oui | non |
rubriqueID | La rubrique dans laquelle est classé le document | solr.TrieLongField | non | oui |
Ce qui nous donne la configuration suivante :
<fields> <field name="monID" type="long" indexed="true" stored="true" required="true"/> <field name="rubriqueID" type=" long " indexed="true" stored="true" required="true"/> <field name="monTexte" type="text" indexed="false" stored="true" required="true"/> <field name="champ1" type="text" indexed="true" stored="false" required="true"/> <field name="champ2" type="text" indexed="true" stored="false" required="false"/> <dynamicField name="*" type="ignored" /> </fields> <uniqueKey>monID</uniqueKey> <defaultSearchField>champ1</defaultSearchField>
C’est dans la section <types> que l’on définit les paramètres d’indexation de chaque type de champ, en paramétrant les analyzers .
Voici un exemple de notre champ de type texte :
<fieldType name="text_fr" positionIncrementGap="100"> <analyzer type="index"> <charFilter mapping="mapping-ISOLatin1Accent.txt"/> <tokenizer/> <!--<filter ignoreCase="true" words="stopwords/stopwords_fr.txt" enablePositionIncrements="true" />--> <filter generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/> <filter/> <filter language="French" protected="protwords.txt"/> </analyzer> <analyzer type="query"> <charFilter mapping="mapping-ISOLatin1Accent.txt"/> <tokenizer/> <!--<filter synonyms="synonyms/synonyms_fr.txt" ignoreCase="true" expand="true"/>--> <!--<filter ignoreCase="true" words="stopwords/stopwords_fr.txt" enablePositionIncrements="true"/>--> <filter generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> <filter/> <filter language="French" protected="protwords.txt"/> </analyzer> </fieldType>
solrconfig.xml
- Commentez la ligne suivante :
<dataDir>${solr.data.dir:./solr/data}</dataDir>
Ceci permet de créer l’index dans le sous-dossier data et non dans le dossier par défaut (C:\Program Files\Apache Software Foundation\Tomcat 6.0\solr\data)
Vérifier la configuration
- Relancez Tomcat pour prendre en compte les modifications.
- Vérifiez que les champs sont bons dans le Shema Browser :
http://localhost:8080/solr/index1/admin/schema.jsp
- En cas d’erreur, aller voir dans les logs de Tomcat.
Mise à jour de l’index
La mise à jour de l’index (ajout, mise à jour, suppression) se fait très simplement par l’envoi en POST d’un flux xml. Chaque élément de l’index est appelé document.
Ajout, modification.
La syntaxe est la même pour les 2 actions. En fait, si le document existe déjà (basé sur sa clé unique), il sera mis à jour, sinon il sera ajouté.
On peut ajouter/mettre à jour plusieurs documents en une seule fois.
Voici la structure du fichier xml à envoyer (basé sur notre exemple ci-dessus) :
<add> <doc> <field name="monID">12</field> <field name="rubriqueID">5</field> <field name="monTexte">le texte à afficher</field> <field name="champ1">mots-clé principaux</field> <field name="champ2">mots-clé secondaires</field> </doc> <doc> <field name="monID">13</field> <field name="rubriqueID">1</field> <field name="monTexte">le texte à afficher</field> <field name="champ1">mots-clé principaux</field> <field name="champ2">mots-clé secondaires</field> </doc> </add>
Il faut ensuite envoyer en POST un autre flux xml contenant une commande COMMIT :
Le contenu du flux xml est tout simple :
<commit/>
On peut également appeler une commande pour optimiser l’index :
<optimize/>
Suppression de documents
Le principe est le même : on envoie dans un premier temps le flux xml des documents à supprimer, puis on effectue un commit.
Le flux xml pour la suppression est simple :
<delete> <id>12</id> <id>13</id> </delete>
Notez que l’on utilise le champ id et non le nom du champ que l’on a donné à notre clé unique (monID).
Exemple d’appel à SolR en ASP
Voici un exemple de code en ASP pour ajouter et supprimer des documents. Vous remarquerez que l’on peut très bien envoyer dans un même flux xml des ajouts et des suppressions.
' On crée le xml xml = "<add>" xml = xml & "<doc>" xml = xml & "<field name=""monID"">12</field>" xml = xml & "<field name=""rubriqueID"">5</field>" xml = xml & "<field name=""monTexte"">" & Server.HtmlEncode("le texte à afficher") & "</field>" xml = xml & "<field name=""champ1"">" & Server.HtmlEncode("mots-clé principaux") & "</field> xml = xml & "<field name=""champ2"">" & Server.HtmlEncode("mots-clé secondaires") & "</field>" xml = xml & "</doc>" xml = xml & "</add>" xml = xml & "<delete>" xml = xml & "<id>13</id>" xml = xml & "</delete>" ' On envoie le contenu Xml vers SolR Set oXml = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0") oXml.Open "POST", "http://localhost:8080/solr/index1/update", False oXml.setRequestHeader "Content-Type", "text/xml" oXml.Send xml If oXml.readyState <> 4 Then oXml.waitForResponse 10 retour = solrRetour(oXml.responseText) ' Commit If retour = 0 Then oXml.Open "POST", " http://localhost:8080/solr/index1/update", False oXml.setRequestHeader "Content-Type", "text/xml" oXml.Send "<commit/>" If oXml.readyState <> 4 Then oXml.waitForResponse 10 retour = solrRetour(oXml.responseText) End If ' TRAITEMENT DU FLUX XML DE RETOUR DES COMMANDES SOLR '---------------------------------------------------- Function solrRetour(xml) Dim oXml, Root, lst, retour Set oXml = Server.CreateObject("MSXML.DOMDocument") oXml.Async=False If Not oXml.loadXml(xml) Then retour = -1 Else Set Root = oXml.documentElement Set lst = Root.selectSingleNode("lst") retour = lst.selectSingleNode("int[@name='status']").text End If solrRetour = retour End Function
Références
Exécuter des requêtes
Là aussi, l’exécution de requêtes est très simple : il suffit d’interroger une page et de récupérer le contenu du flux xml.
Structure de la requête
Voici un exemple d’url :
http://localhost:8080/solr/index1/select?qt=dismax&q=les+mots+cles&qf=champ1^1+champ2^0.6&start=0&rows=25&fl=monID,monTexte,score&fq=rubriqueID:5
Détaillons les paramètres :
Champ | Valeur |
---|---|
qt (query type) | dismax : ce type de requête permet la pondération des champs de recherche |
q (query) | La liste des mots clés |
qf (query fields) | Liste des champs dans lesquels doit s’effectuer la recherche (champs indexés uniquement). On peut pondérer ces champs en ajoutant ^x où x est le coefficient de pondération. |
start, rows | Permet de ne récupérer qu’une partie des résultats pour générer une pagination par exemple. – start est la position du 1ere résultat à afficher – rows est le nombre de résultats à récupérer. |
fl (field list) | Liste des champs à renvoyer dans le flux xml, séparés par des virgules. Le champ spécial score renvoit le score calculé poar SolR |
fq (filter query) | Permet de restreindre la recherche à certaines valeurs de certains champs (ici, on ne récupère que les documents de la rubrique n° 5) |
Exemple de code en ASP :
url = "http://localhost:8080/solr/index1/select?..." Set oXmlSolr = Server.CreateObject("MSXML2.ServerXMLHTTP") Set oXml = Server.CreateObject("MSXML.DOMDocument") oXml.Async=False oXmlSolr.Open "GET", url ,False oXmlSolr.Send() Set Root = oXml.documentElement Set result = Root.selectSingleNode("result") nbResults = result.GetAttribute("numFound") For Each doc in result.ChildNodes Response..Write (doc.selectSingleNode("str[@name='monTexte']").text) Next
http://vm-win2003-01:8080/solr/aafr/select?indent=on&q=chargeur&rows=10&fl=*+score&qt=dismax&qf=Champ1^1+Champ2^0.6+Champ3^0.3
http://vm-win2003-01:8080/solr/aafr/select?q=moissonneuse&fq=&start=0&rows=100&fl=produitID,HTML,score&qt=dismax&qf=Champ1^0.6+Champ2^0.3+Champ3^0.1
Références
Réplication
On considère pour cette étape qu’aucun index n’a encore été généré (dossier data vide).
Configuration du serveur maître
- Editez le fichier solrConfig.xml et décommentez et adaptez la partie suivante:
(la section slave doit être correctement configurée avec l’adresse du maître et commentée.)<requestHandler name="/replication" > <lst name="master"> <str name="replicateAfter">commit</str> <str name="replicateAfter">optimize</str> <str name="replicateAfter">startup</str> <str name="confFiles">solrconfig_slave.xml:solrconfig.xml,schema.xml</str> </lst> <!-- <lst name="slave"> <str name="masterUrl">http://192.168.2.35:8080/solr/index1/replication</str> <str name="pollInterval">00:00:60</str> </lst> --> </requestHandler>
- Dupliquez le fichier solrconfig.xml en solrconfig_slave.xml.
(ceci permet d’appliquer toutes les modifications sur le maître et de répliquer la configuration sur les esclaves (le fichier solrconfig_slave.xml sera automatiquement renommé en solrconfig.xml).
- Editez le fichier solrconfig_slave.xml, commentez la partie master et décommentez la partie slave.
- Redémarrez Tomcat.
Sur l’esclave
- Installez Tomcat et Solr en suivant la procédure jusqu’à l’étape “Configuration de Tomcat” incluse mais ne redémarrez pas Tomcat tout de suite.
- Recopiez lecontenu du dossier de l’index du maître dans le dossier de l’index correspondant sur l’esclave.
- Renommez solrconfig_slave.xml en sorlconfig.xml.
- Lancez Tomcat.
- Vérifiez que la réplication fonctionne en appelant cette url directement sur le serveur esclave :
http://<ip_esclave>:8080/solr/aa/admin/replication/
Références
- http://wiki.apache.org/solr/SolrReplication
- http://techgurulive.com/2009/12/14/how-to-configure-apache-solr-replication/
Compléments d’information
Gestion des accents et similitudes
ex : élévateur, elevateur, élevateur
Utilisez un champ text spécifique avec le filtre suivant (analyzer index + query) :
<charFilter mapping="mapping-ISOLatin1Accent.txt"/>
Configurer les index pour une indexationavec une base de données MySQL
On peut indexer directement une base de données MySQL. Voici une ébauche concernant la façon de paramétrer l’indexation MySQL (non
testée).
Récupérer le driver JDBC MySQL
Copier le fichier mysql-connector-java-<version>-bin.jar dans <home>\lib.
http://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.5
https://code.google.com/p/stavkovakancelaria/downloads/detail?name=mysql-connector-java-5.1.5-bin.jar&can=2&q=
Paramétrer l’accès aux données
- Dans le dossier conf, créez un fichier dataconfig.xml, copiez le code ci-dessous et adaptez-le (champs en rouge) :
<?xml version="1.0" encoding="UTF-8"?> <dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/database" user="user" password="password"/> <document name="doc"> <entity name="jos_content" query="SELECT * FROM matable WHERE state=1" deltaImportQuery="SELECT * FROM matable WHERE tableID='${dataimporter.delta.job_jobs_id}'" deltaQuery="SELECT tableID FROM matable WHERE modified > '${dataimporter.last_index_time}'"> <field column ="tableID" name="monID" /> <field column="tableTexte" name="monTexte" /> <field column="rubriqueID" name="rubriqueID" /> </entity> </document> </dataConfig>
- Dans le fichier solrconf.xml, ajoutez le requestHandler suivant :
<requestHandler name="/dataimport"> <lst name="defaults"> <str name="config">dataconfig.xml</str> </lst> </requestHandler>
- Dans le fichier solrconf.xml, commentez la ligne <dataDir>.
- Lancer l’indexation complète avec l’url suivante :
http://vm-win2003-01:8080/solr/aafr/dataimport?command=full-import
Problème de mémoire
Si vous obtenez un message d’erreur indiquant un problème de mémoire, ajouter batchSize=”-1″ à la connexion mysql dans dataconfig.xml, ce qui nous donne :
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/database" batchSize="-1" user="user" password="password"/>
Références
- http://www.cabotsolutions.com/blog/200905/using-solr-lucene-for-full-text-search-with-mysql/
- http://wiki.apache.org/solr/DataImportHandlerFaq