Solr : mise à jour des données

Implémenter Solr dans une application web Java

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com
Jusque là on a pu voir comment importer les données au Solr. Cependant, cette opération est gourmande en ressources et sa répétitivité peut s'avérer fatiguante pour le système. C'est pourquoi on va aborder maintenant la maintenance des documents indexés.

Solr, comme tout moteur de recherche, permet de maintenir les documents en état cohérent. Sans aucun problème on peut supprimer un document ou bien le mettre à jour. Dans cet article on verra quelques exemples de maintenance d'un index Solr, en expliquant la suppression des données. Pour montrer cette opération on supprimera les deux pays rajoutés précédemment, RFN et DDR.

Supprimer les données dans Solr
Pour la suppression on utilisera un document XML. Ce document est composé d'une balise <delete />. Là-dedans on spécifie les conditions de suppression. Elles sont comprises dans la balise <query />. Les conditions peuvent concerner les valeurs spécifiées dans les champs, mais pas que. Elles peuvent également représenter le temps. Grâce à cela on peut, par exemple, supprimer des documents rajoutés pendant les dernières 24 heures.

Les deux utilisations emploient le syntaxe de requêtage de Solr. Il sera présenté dans le prochain article. Actuellement on se contentera donc des conditions simples, du genre MySQL "WHERE id = 3", "WHERE id = 3 AND first_name = 'Sylvie'" ou "WHERE date > CURDATE()". Plus loin on en découvrira d'autres qui seront appliquables aussi bien à la sélection qu'à la suppression.

Suppimer les documents Solr par champ
Dans un premier temps on verra le moyen plus simple de suppression, celui par les conditions liées aux champs. Regardons d'abord notre code Solrj qui permettra d'effectuer les requêtes de suppression :

SolrServer solrServer = new HttpSolrServer("http://localhost:8080/world");
// can be done with solrServer.deleteById(255); too
SolrResponse solrResponse = solrServer.deleteByQuery("id:255");
System.out.println("Received response : " + solrResponse.toString());


Vraiement rien de compliqué. Au débout on initialise le serveur. Ensuite on appelle une des méthodes du serveur, SolrServer.deleteByQuery() en lui spécifiant les conditions de suppression. En occurrence, il s'agit de la condition "identifiant égal à 255". Il faut aussi regarder le commentaire car SolrServer fournit des méthodes permettant d'effectuer cette opération directement. Il s'agit de deleteById qui peut prendre en paramètre aussi bien un identifiant que plusieurs (sous forme d'un List<String>).

Après avoir effectué cette requête, on s'aperçoit que le pays 255 a été supprimé. Voici la requête de vérification : http://localhost:8080/world/query?indent=on&version=2.2&qt=&q=id:255&start=0&rows=10&fl=&debugQuery=on&explainOther=&hl.fl=&fq= qui donne cela :

"responseHeader":{
"status":0,
"QTime":1,
"params":{
"explainOther":"",
"fl":"",
"debugQuery":"on",
"indent":"on",
"start":"0",
"q":"id:255",
"hl.fl":"",
"qt":"",
"fq":"",
"version":"2.2",
"rows":"10"}},
"response":{"numFound":0,"start":0,"docs":[]
},


Au tout début on a mentionné la possibilité de supprimer les champs par plusieurs conditions. Regardons comment supprimer le pays RFN par son nom et son code ISO (fictif) RF. Cependant, dans un premier temps on indiquera le mauvais code ISO (RFX) pour prouver que la suppressio ne fonctionnera pas. Voici la requête qui se trouvera dans la méthode deleteByQuery : (countryName:RFN)AND(iso:RFX). Et voici la condition qui marchera : (countryName:RFN)AND(iso:RF). On remarque que les deux conditions sont regroupées entre parenthèses et séparées par un mot AND. Dans l'article prochain on verra d'autres méthodes de joindre plusieurs conditions.

Supprimer les données récentes dans Solr
Pour pouvoir manipuler les données avec les conditions temporaires, il faut rajouter un champ dans notre schéma. Ce champ s'occupera de stocker le jour de la dernière modification d'un document. Il se présente ainsi :

<fields>
<field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
</fields>

<types>
<fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
</types>


Ses attributs sont suffisament explicits pour pouvoir les ignorer et passer directement à la requête de suppression. Bien sûr, avant son exécution, il faut réimporter les pays à supprimer : RFN et DDR. Alors, le nouveau champ contiendra la date de l'indexation.

Maintenant on peut effectuer la suppression de ces 2 champs, à travers la requête : timestamp:[NOW-24HOUR TO NOW]. Qu'est-ce qu'elle signifie ? La première valeur représente le champ concerné. Ensuite entre crochets les deux conditions sont : NOW-24HOUR et NOW. La première veut dire que nous sommes intéressés par tous les documents indexés depuis hier. La seconde signifie la date limite de l'indexation. En occurrence, aujourd'hui. Suite à l'exécution de cette requête, les deux documents rajoutés il y a quelques minutes à peine (donc aujourd'hui - quelques minutes), seront supprimés.

On s'en aperçoit en appelant ces deux URLs : http://localhost:8080/world/query?indent=on&version=2.2&qt=&q=countryName:RFN&start=0&rows=10&fl=&debugQuery=on&explainOther=&hl.fl=&fq= et http://localhost:8080/world/query?indent=on&version=2.2&qt=&q=countryName:DDR&start=0&rows=10&fl=&debugQuery=on&explainOther=&hl.fl=&fq=. Les deux donneront la même réponse :

"responseHeader":{
"status":0,
"QTime":1,
"params":{
"explainOther":"",
"fl":"",
"debugQuery":"on",
"indent":"on",
"start":"0",
"q":"countryName:DDR",
"hl.fl":"",
"qt":"",
"fq":"",
"version":"2.2",
"rows":"10"}},
"response":{"numFound":0,"start":0,"docs":[]
}


A travers cet article on a vu qu'il est facile de maintenir nos indexes en bon état. Les requêtes de suppression utilisent le même syntaxe que les requêtes de sélection. Il n'est donc pas nécessaire d'apprendre de nouvelles méthodes. Juste l'appel d'une nouvelle fonction suffit.
Bartosz KONIECZNY 08-09-2013 17:23 Solr
Moi

Développeur d'applications Internet et journaliste passionné par l'adjectif français. Un aigle polonais orienté vers la progression, volant très haut et écoutant du zouk après les matches du foot français.

Vous appréciez mon travail ?

Pour contribuer au développement de ce site, ou pour remercier pour des articles rédigés, vous pouvez faire un don.

Un conseil Zend Framework

Comment faciliter le travail entre notre application et l'Ajax ?

L'un des moyens est l'utilisation du ContextSwitch. Il permet de définir le type de réponse renvoyé.