So schreiben Sie eine SPARQL-Abfrage, die String-Literale effizient abgleicht und dabei die Groß-/Kleinschreibung ignoriert

StackOverflow https://stackoverflow.com//questions/10660030

  •  11-12-2019
  •  | 
  •  

Frage

Ich verwende Jena ARQ, um eine SPARQL-Abfrage für eine große Ontologie zu schreiben, die aus Jena TDB gelesen wird, um die Typen zu finden, die mit Konzepten basierend auf dem RDFS-Label verknüpft sind:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> "aspirin" .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}

Das funktioniert ziemlich gut und ist tatsächlich ziemlich schnell (<1 Sekunde).Leider muss ich diese Abfrage bei einigen Begriffen ohne Berücksichtigung der Groß- und Kleinschreibung durchführen.Zum Beispiel wegen des Etiketts "Tylenol" steht in der Ontologie, aber nicht "tylenol", die folgende Abfrage bleibt leer:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> "tylenol" .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}

Ich kann eine Version dieser Abfrage ohne Berücksichtigung der Groß- und Kleinschreibung mit der FILTER-Syntax wie folgt schreiben:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
 FILTER ( regex (str(?term), "tylenol", "i") )
}

Aber jetzt dauert die Abfrage über eine Minute!Gibt es eine Möglichkeit, die Abfrage ohne Berücksichtigung der Groß- und Kleinschreibung effizienter zu schreiben?

War es hilfreich?

Lösung

Der Grund dafür, dass die Abfrage mit der FILTER-Abfrage langsamer ausgeführt wird, liegt darin, dass ?term ungebunden ist. Daher muss der PSO- oder POS-Index gescannt werden, um alle Anweisungen mit dem Prädikat rdfs:label zu finden und sie anhand des regulären Ausdrucks zu filtern.Wenn es an eine konkrete Ressource gebunden war (in Ihrem ersten Beispiel), könnte es einen OPS- oder POS-Index verwenden, um nur Anweisungen mit dem Prädikat rdfs:label und der angegebenen Objektressource zu durchsuchen, die eine viel geringere Kardinalität hätten.

Die übliche Lösung für diese Art von Textsuchproblemen ist die Verwendung eines externen Textindex.Für diesen Fall stellt Jena einen Freitextindex namens LARQ, das Lucene zur Durchführung der Suche verwendet und die Ergebnisse mit dem Rest der Abfrage verknüpft.

Andere Tipps

Von allen möglichen String-Operatoren, die Sie in SPARQL verwenden können, ist regex ist wahrscheinlich das teuerste.Wenn Sie dies vermeiden, wird Ihre Abfrage möglicherweise schneller ausgeführt regex und du verwendest UCASE oder LCASE stattdessen auf beiden Seiten des Tests.Etwas wie:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
 FILTER (lcase(str(?term)) = "tylenol")
}

Dies ist möglicherweise schneller, aber im Allgemeinen ist bei der Textsuche mit einem Dreifachspeicher keine große Leistung zu erwarten.Triple Stores sind sehr gut im Graph-Matching und nicht so gut im String-Matching.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top