SpazioCodice

RDF in Solr : Comment faire

Le gestionnaire intégré de UpdateRequestHandler de Solr prend en charge plusieurs formats de données d’entrée. Il délègue le chargement réel des données à un ContentStreamLoader, spécifique, en fonction du type de contenu de la requête entrante (c’est-à-dire, l’en-tête Content-type de la requête HTTP). Actuellement, voici les types de contenu disponibles déclarés dans la classe UpdateRequestHandler :

  • application/xml ou text/xml
  • application/json ou text/json
  • application/csv ou text/csv
  • application/javabin

Ainsi, un client a plusieurs options pour envoyer ses données à Solr ; tout ce qu’il a à faire est de préparer ces données dans un format spécifique et d’appeler le UpdateRequestHandler (généralement situé à l’endpoint /update), en spécifiant le type de contenu correspondant.

				
					> curl http://localhost:8080/solr/update \
  -H "Content-Type: text/json" \
  --data-binary @/home/agazzarini/data.json

				
			

Le UpdateRequestHandler peut être étendu, personnalisé et remplacé, ce qui permet de créer notre propre UpdateRequestHandler qui accepte un format personnalisé, en ajoutant un nouveau type de contenu ou en remplaçant l’ensemble des types de contenu par défaut.

Dans cet article, je vais décrire comment utiliser

Jena pour charger des données RDF dans Solr dans n’importe quel format pris en charge par le Jena IO API.

Cela est une tâche rapide et facile principalement parce que :

  • Le UpdateRequestHandler possède déjà la logique pour indexer les données.
  • Le UpdateRequestHandler peut être facilement étendu.
  • Jena fournit déjà tous les parseurs dont nous avons besoin.

Donc, pour cela, il suffit de sous-classer le UpdateRequestHandler pour remplacer le registre des types de contenu :

				
					public class RdfDataUpdateRequestHandler extends UpdateRequestHandler
...
    protected Map createDefaultLoaders(NamedList parameters) {
           final Map<String, ContentStreamLoader> registry 
                      = new HashMap<String, ContentStreamLoader>();
           final ContentStreamLoader loader = new RdfDataLoader();
           for (final Lang language : RDFLanguages.getRegisteredLanguages()) {
                  registry.put(language.getContentType().toHeaderString(), loader);
           }
           return registry;
    }
    ...
}
				
			

Comme vous pouvez le voir, le registre est une simple carte qui associe un type de contenu (par exemple, “application/xml”) à une instance de ContentStreamLoader.

Dans notre exemple, puisque les différents types de contenu correspondront toujours aux données RDF, nous créons une instance d’un ContentStreamLoader dédié (RdfDataLoader) une fois ; cette instance sera associée à tous les types de contenu intégrés dans Jena. Cela signifie qu’à chaque fois qu’une requête entrante aura un type de contenu comme :

  • text/turtle
  • application/turtle
  • application/x-turtle
  • application/rdf+xml
  • application/rdf+json
  • application/ld+json
  • text/plain (pour n-triple)
  • application/n-triples
  • (autres)

Notre RdfDataLoader sera responsable de l’analyse et du chargement des données. Notez que la liste ci-dessus n’est pas exhaustive ; il existe de nombreux autres types de contenu enregistrés dans Jena (voir la classe RDFLanguages).

Alors, qu’en est-il du format des données ? Bien sûr, cela dépend toujours du type de contenu de vos données RDF, et surtout, cela n’a rien à voir avec les données que nous envoyons habituellement à Solr (c’est-à-dire des SolrInputDocuments sérialisés dans un format quelconque).

Le RdfDataLoader est une sous-classe de ContentStreamLoader :

				
					public class RdfDataLoader extends ContentStreamLoader {

...

    public void load()
                final SolrQueryRequest request,
                final SolrQueryResponse response,
                final ContentStream stream,
                final UpdateRequestProcessor processor) throws Exception {
    
            final PipedRDFIterator<Triple> iterator = new PipedRDFIterator<Triple>();
            final PipedRDFStream<Triple> inputStream  = new PipedTriplesStream(iterator);    
            // We use an executor for running the parser in a separate thread
            final ExecutorService executor = Executors.newSingleThreadExecutor();
            final Runnable parser = new Runnable() {
                  public void run() {
                       try {
                            RDFDataMgr.parse(
                                inputStream,
                                stream.getStream(),
                                RDFLanguages.contentTypeToLang(stream.getContentType()));
                       } catch (final IOException exception) {
                          ...
                       }
                  }
            };
    
            executor.submit(parser);
            while (iterator.hasNext()) {
              final Triple triple = iterator.next();
                // create and populate the Solr input document
                final SolrInputDocument document = new SolrInputDocument();
                ...
                 // create the update command
                final AddUpdateCommand command  = new AddUpdateCommand(request);
                // populate it with the input document we just created
                command.solrDoc = document;
    
                // add the document to index
                processor.processAdd(command);
            } 
    }

}
				
			

C’est tout ! Une fois que le gestionnaire de requêtes a été enregistré dans Solr, nous pouvons envoyer des données RDF à Solr en utilisant une commande comme celle-ci :

				
					> curl http://localhost:8080/solr/update \
  -H "Content-Type: text/json" \
  --data-binary @/home/agazzarini/data.json

				
			

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