Accueil > Intégration avec le connecteur Lucene de GraphDB
Intégration avec le connecteur Lucene de GraphDB
Introduction
GraphDB propose une intégration avec Lucene en utilisant le connecteur Lucene de GraphDB. Ce connecteur permet de créer de puissants index de texte intégral des propriétés de texte dans le graphe, et d’écrire des requêtes qui combinent à la fois des critères de texte intégral et de graphe, tels que “Donnez-moi la liste des musées qui exposent une œuvre d’art dont le titre contient le mot ‘paix’“
Sparnatural peut être intégré à un tel index Lucene de GraphDB à la fois pour alimenter les champs d’autocomplétion et également pour la génération de requêtes SPARQL comme décrit ci-dessous.
Créer l’index
Reportez-vous à la documentation du connecteur Lucene de GraphDB pour plus de détails. Voici l’idée :
- Déterminez l’URI de la classe pour laquelle vous souhaitez construire l’index ;
- Énumérez chaque propriété littérale ou chemin à stocker dans l’index ;
- Typiquement des libellés, des noms, des titres, des définitions, des résumés, etc.
- mais aussi la littérale des entités liées dans le graphe, tels que le nom du lieu où un événement a eu lieu, le nom de l’auteur d’une œuvre, les libellés de concepts de sujet, etc.
- Chacune de ces propriétés ou chemin ira dans un champ séparé de l’index ;
- Créez un champ “catchAll” nommé
text
qui concaténera chaque autre champ en un seul ; - Définissez une langue et un analyseur personnalisés si vous avez besoin d’avoir un indexation liée à la langue telle que le pliage des accents en français ;
Exemple : créer un index sur les concepts SKOS en français
Créer des champs individuels
- Dans GraphDB Workbench, allez à “Configuration > Connecteurs”, et créez un nouveau connecteur Lucene ;
- Définissez son nom sur
ConceptIndex
- Dans le champ des langues, saisissez
fr
- Dans le champ “Types”, saisissez l’URI complet pour indexer tous les concepts SKOS : http://www.w3.org/2004/02/skos/core#Concept
- Remplissez l’entrée “Champs” pour indexer les
skos:prefLabel
s :- Nom du champ = prefLabel
- Chaîne de propriété = http://www.w3.org/2004/02/skos/core#prefLabel
- Décochez la case “facet”
- Ajoutez une nouvelle entrée “Field” en cliquant sur le “+” à droite, cette fois pour les
skos:altLabel
s :- Nom du champ = altLabel
- Chaîne de propriétés = http://www.w3.org/2004/02/skos/core#altLabel
- Décochez la case “facet”
- Répétez pour
skos:hiddenLabel
si nécessaire skos:definition
si nécessaireskos:scopeNote
si nécessaireskos:example
si nécessaire
Créer un champ de regroupement
Ensuite, nous devons créer un nouveau champ text
qui va agréger le contenu de tous les autres champs. Pour ce faire, déclarez un nouveau “champ virtuel” nommé text/prefLabel
pour indiquer que le contenu ou le champ prefLabel
doit être copié dans le champ text
(reportez-vous aux parties sur copy-fields combinées avec multiple property paths par champ pour plus de détails) :
- Créez un nouveau champ nommé
text/prefLabel
- Dans le chemin de propriété, saisissez
@prefLabel
; cela doit correspondre au nom de l’un des champs créés précédemment, donc si vous avez choisi des noms différents, ajustez en conséquence ; - Décochez “facet”
- Répétez en ajoutant à nouveau un nouveau champ, nommé
text/altLabel
et chemin de propriété@altLabel
- Répétez avec
text/hiddenLabel
et chemin de propriété@hiddenLabel
- Répétez avec
text/definition
et chemin de propriété@definition
- Répétez avec
text/scopeNote
et chemin de propriété@scopeNote
- Répétez avec
text/example
et chemin de propriété@example
Voici à quoi ressemble cette partie :
Définir la langue et l’analyseur
- Dans le champ
Languages
, définissez la valeurfr
- Dans le champ
Analyzer
, saisissez la valeur de l’analyseur français Luceneorg.apache.lucene.analysis.fr.FrenchAnalyzer
. Si vous ne le faites pas, la recherche sera sensible aux accents (par exemple, une recherche sur “metal” ne correspondra pas à “métal”);
Tester une requête SPARQL
Testez une recherche SPARQL comme suit :
PREFIX : <http://www.ontotext.com/connectors/lucene#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?uri ?label ?snippetField ?snippet WHERE {
# replace "ConceptIndex" with the name of the index at the end of this URI
?search a <http://www.ontotext.com/connectors/lucene/instance#ConceptIndex> .
# replace with a string to search. Also try with different fields, e.g. "altLabel:foo" or "text:foo" or with no field at all e.g. "foo"
?search :query "prefLabel:foo" .
?search :entities ?uri .
?uri :snippets _:s .
_:s :snippetField ?snippetField ;
:snippetText ?snippet .
?uri skos:prefLabel ?prefLabel . FILTER(lang(?prefLabel) = $lang)
Alimenter un champ d’autocomplétion dans Sparnatural avec SPARQL en utilisant GraphDB Lucene Connector
Le principe est le suivant :
- Comme indiqué dans la documentation de configuration Sparnatural pour vos propres requêtes, la requête SPARQL DOIT renvoyer 2 variables :
?uri
et?label
; - Définissez une chaîne de requête SPARQL personnalisée pour la définition du champ d’autocomplétion, en utilisant des opérateurs spéciaux
:query
pour interroger l’index; - Ajoutez un “*” après la clé de recherche pour rechercher le début des mots;
- Interrogez le champ de recherche général, donc
text
dans notre cas; - Générez une variable
label
en concaténant le prédicat skos:prefLabel de l’entité avec son extrait des résultats de la recherche
Voici un exemple de requête :
PREFIX : <http://www.ontotext.com/connectors/lucene#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?uri ?label WHERE {
# replace "ConceptIndex" with the name of the index at the end of this URI
?search a <http://www.ontotext.com/connectors/lucene/instance#ConceptIndex> .
# Replace 'foo' with a test query, but keep the final "*" character
?search :query "text:foo*" .
?search :entities ?uri .
?uri :snippets _:s .
_:s :snippetField ?snippetField ;
:snippetText ?snippet .
# get the skos:prefLabel predicate of the concept in the proper language
?uri skos:prefLabel ?prefLabel . FILTER(lang(?prefLabel) = "fr")
# generate a "label" to display in autocomplete result, by concatenating skos:prefLabel, line break, and snippet in small font
BIND(CONCAT(STR(?prefLabel), '<br /><small>', ?snippet ,'</small>') AS ?label)
}
Et voici une requête intégrée dans une configuration JSON-LD de Sparnatural. Notez comment elle utilise les espaces réservés $domain
, $range
, $property
, $key
et $lang
qui sont remplacés au moment de la requête par des valeurs réelles :
{
"@id" : "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto#type-decouverte",
"@type" : "ObjectProperty",
"subPropertyOf" : "sparnatural:AutocompleteProperty",
"label": [
{"@value" : "discovery type","@language" : "en"},
{"@value" : "type de découverte","@language" : "fr"}
],
"domain": "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto#Site",
"range": "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto#Concept",
"sparqlString": "<http://www.cidoc-crm.org/cidoc-crm/P2_has_type>",
"datasource": {
"queryString": "\
PREFIX : <http://www.ontotext.com/connectors/lucene#>\
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>\
SELECT DISTINCT ?uri ?label WHERE {\
?something a $domain .\
?something $property ?uri .\
?search a <http://www.ontotext.com/connectors/lucene/instance#ConceptIndex> .\
?search :query \"text:$key*\" .\
?search :entities ?uri .\
?uri :snippets _:s .\
_:s :snippetField ?snippetField ;\
:snippetText ?snippet .\
?uri skos:prefLabel ?prefLabel . FILTER(lang(?prefLabel) = $lang)\
BIND(CONCAT(STR(?prefLabel), '<br /><small>', ?snippet ,'</small>') AS ?label)\
}"
}
Intégration avec la génération de requêtes SPARQL
Vous pouvez configurer Sparnatural pour générer des requêtes SPARQL qui interrogeront l’index de texte intégral. Pour ce faire :
- Créez une classe dans la configuration Sparnatural avec l’URI de l’index, par exemple
http://www.ontotext.com/connectors/lucene/instance#ConceptIndex
. Créez cette classe en tant quesubClassOf http://www.w3.org/2000/01/rdf-schema#Literal
, et donnez-lui un libellé tel que “Recherche en texte intégral…”; - Créez des propriétés qui correspondent aux champs de l’index. Les URI des propriétés doivent se terminer par le nom du champ de l’index, après le dernier “#” ou la dernière “/”. Par exemple,
http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto/search#discovery
interrogera le champdiscovery
; - Définissez la propriété comme
subPropertyOf sparnatural:GraphDBSearchProperty
; ce paramètre indique à Sparnatural que la requête à générer doit utiliser la syntaxe GraphDB et non la syntaxe FILTER habituelle; - Créez plusieurs propriétés pour chaque champ de l’index, afin que l’utilisateur puisse choisir le champ à interroger.
Voici un exemple de configuration avec 2 propriétés configurées pour interroger les champs commune
et discovery
, et une troisième propriété nommée “tous les champs” pour interroger le champ de recherche général :
{
"@id" : "http://www.ontotext.com/connectors/lucene/instance#SiteIndex",
"@type" : "Class",
"subClassOf" : "http://www.w3.org/2000/01/rdf-schema#Literal",
"label": [
{"@value" : "Full-text search...","@language" : "en"},
{"@value" : "Recherche plein-texte...","@language" : "fr"}
],
"faIcon": "fad fa-search"
},
...
{
"@id" : "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto/search#commune",
"@type" : "ObjectProperty",
"subPropertyOf" : "sparnatural:GraphDBSearchProperty",
"label": [
{"@value" : "city","@language" : "en"},
{"@value" : "commune","@language" : "fr"}
],
"domain": "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto#Site",
"range": "http://www.ontotext.com/connectors/lucene/instance#SiteIndex"
},
{
"@id" : "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto/search#discovery",
"@type" : "ObjectProperty",
"subPropertyOf" : "sparnatural:GraphDBSearchProperty",
"label": [
{"@value" : "discovery","@language" : "en"},
{"@value" : "type de découverte","@language" : "fr"}
],
"domain": "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto#Site",
"range": "http://www.ontotext.com/connectors/lucene/instance#SiteIndex"
},
{
"@id" : "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto/search#text",
"@type" : "ObjectProperty",
"subPropertyOf" : "sparnatural:GraphDBSearchProperty",
"label": [
{"@value" : "any field","@language" : "en"},
{"@value" : "tous les champs","@language" : "fr"}
],
"domain": "http://labs.sparna.fr/sparnatural-demo-graphdb-openarchaeo/onto#Site",
"range": "http://www.ontotext.com/connectors/lucene/instance#SiteIndex"
},
Ce qui donnera le comportement suivant pour l’utilisateur final :