SpazioCodice

Apache Solr : Chargement des données au démarrage

SolrEventListener est une interface qui définit un ensemble de rappels pour plusieurs événements du cycle de vie :

  • void postCommit()
  • void postSoftCommit()
  • void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher)

Dans cet exemple, je ne suis pas intéressé par les deux premiers rappels car les invocations correspondantes se produiront, comme leur nom l’indique, après les événements de commit dur et doux. Le méthode intéressante est newSearcher(...), qui permet d’enregistrer un écouteur d’événements personnalisé associé à deux événements :

  • firstSearcher
  • newSearcher

Dans Solr, le IndexSearcher qui sert les requêtes à un moment donné est appelé le currentSearcher. Au démarrage, il n’y a pas de currentSearcher car le premier est créé ; nous sommes donc dans l’événement “firstSearcher”, ce qui est exactement ce que je recherchais.

Lorsqu’un autre (nouveau) searcher est ouvert, il est préparé (c’est-à-dire automatiquement réchauffé) pendant que l’actuel continue de servir les requêtes entrantes. Lorsque le nouveau searcher est prêt, il devient le currentSearcher, il traitera toutes les nouvelles requêtes de recherche, et l’ancien searcher sera fermé (dès que toutes les requêtes qu’il traitait sont terminées). Ce scénario est celui où le rappel “newSearcher” est invoqué.

Comme vous pouvez le voir, la méthode de rappel pour ces deux événements est la même ; il n’y a pas de méthode “firstSearcher” et “newSearcher”. La différence réside dans les arguments d’entrée : pour les événements “firstSearcher”, il n’y a pas de currentSearcher, donc le deuxième argument est nul ; ce n’est évidemment pas le cas pour les rappels “newSearcher”, où les deux premiers arguments contiennent une référence valide au searcher.

En revenant à mon scénario, tout ce dont j’ai besoin :

  • déclarer cet écouteur dans solrconfig.xml
  • une implémentation concrète de SolrEventListener

Dans solrconfig.xml, au sein de la section <updateHandler>, je peux déclarer mon écouteur :

				
					<listener event="firstSearcher" class="a.b.c.SolrStartupListener">
    <str name="datafile">${solr.solr.home}/sample/data.xml&lt;/str>
</listener>
				
			

L’écouteur sera initialisé avec un seul paramètre, le fichier contenant les données d’exemple. En utilisant l’attribut “event”, je peux informer Solr du type d’événement qui m’intéresse (par exemple firstSearcher).

La classe d’implémentation est assez simple : elle étend SolrEventListener :

				
					public class SolrStartupListener implements SolrEventListener {
...

    @Override
    public void init(final NamedList args) {
        this.datafile = (String) args.get("datafile");
    }
    ...
    
    LocalSolrQueryRequest request = null;
    try {
           // 1. Create the arguments map for the update request
           final NamedList args = new SimpleOrderedMap();
            args.add(
                    UpdateParams.ASSUME_CONTENT_TYPE,  
                    "text/xml");
            addEventParms(currentSearcher, args);

            // 2. Create a new Solr (update) request
            request = new LocalSolrQueryRequest(
                     newSearcher.getCore(), 
                     args);
           
            // 3. Fill the request with the (datafile) input stream
            final List streams = new ArrayList();
            streams.add(new ContentStreamBase() {
                @Override
                public InputStream getStream() throws IOException {
                    return new FileInputStream(datafile);
                }
            });
           
            request.setContentStreams(streams);
           
            // 4. Creates a new Solr response
            final SolrQueryResponse response = 
                new SolrQueryResponse();
           
            // 5. And finally call invoke the update handler
            SolrRequestInfo.setRequestInfo( 
                new SolrRequestInfo(request, response))

            newSearcher
                 .getCore()
                 .getRequestHandler("/update")
                 .handleRequest(request, response);    
  
        } finally {
            request.close();
        }
    }
}
				
			

Voilà : si vous démarrez Solr, vous verrez les données d’exemple chargées. En plus d’éviter beaucoup de tâches répétitives, cela peut être utile lorsque vous utilisez un SolrCore comme stockage NoSQL, par exemple si vous stockez des vocabulaires SKOS pour les synonymes, les traductions et les recherches plus larges / plus étroites.

Share this post

Laisser un commentaire

En savoir plus sur SpazioCodice

Abonnez-vous pour poursuivre la lecture et avoir accès à l’ensemble des archives.

Poursuivre la lecture