lobid-gnd: Formulierung komplexer Suchanfragen

06 Jul 2018, Adrian Pohl, Fabian Steeg | 🏷 lobid-gnd 

Im vorherigen Beitrag haben wir bereits die Oberfläche von lobid-gnd und ihre Funktionen beschrieben. Die API ermöglicht aber auch komplexere Abfragen, für die man sich ein wenig mit den zugrundeliegenden Datenstrukturen vertraut machen muss. Dies soll in diesem Beitrag an einigen Beispielen ausgeführt werden.

Query-Grundlagen

Bevor wir die Suchmöglichkeiten an einigen Beispielen illustrieren, werden zunächst einige generelle Informationen zur Suche geliefert.

Eingabe

Alle Abfragen können über das Suchfeld auf der lobid-gnd-Seite eingegeben werden:

Screenshot

Die Queries auch direkt als Teil der URL angegeben und im Browser geöffnet werden:

http://lobid.org/gnd/search?q=Dom+Köln

Oder auf der Kommandozeile via curl:

$ curl "http://lobid.org/gnd/search?q=Dom+K%C3%B6ln"

Default-Sucheinstellungen & boolesche Operatoren

Standardmäßig geht eine im Suchfenster angestoßene Suche über alle Felder. Mehrere Suchterme werden dabei per default mit einem booleschen AND verknüpft. Boolesche Operatoren lassen sich aber auch passgenau für den jeweiligen Zweck angeben. Beispiele:

Anzeige der JSON-Daten

In den folgenden Beispielen wird immer wieder auf die strukturierten Daten im Format JSON-LD Bezug genommen, die es für jeden Eintrag in lobid-gnd gibt. Anzeigen lassen sich diese wie folgt:

  1. Mit Klick auf das JSON-LD-Zeichen in einer Detailansicht: Screenshot
  2. Durch Anhängen von .json an die URL eines Einzeltreffers, z.B. http://lobid.org/gnd/11850391X.json
  3. Der Vollständigkeit halber: Bei Suchanfragen muss der Parameter format=json angehängt werden, um die gesamte Ergebnisliste als JSON-LD anzuzeigen, z.B. http://lobid.org/gnd/search?q=hannah+arendt&format=json. (Alternativ können auch mit dem Parameter format=jsonl JSON Lines ausgegeben werden, d.h. pro Zeile ein Eintrag als JSON, z.B. http://lobid.org/gnd/search?q=hannah+arendt&format=jsonl).

Die Bedeutung eines Feldes lässt sich im JSON-LD-Kontext unter http://lobid.org/gnd/context.jsonld nachschlagen. Will ich beispielsweise wissen, wie das Feld broaderTermPartitive verwendet wird, dann suche ich im JSON-LD-Kontext nach diesem Feld und folge dem angegebenen Link zur Beschreibung der zugrundeliegenden RDF-Property, hier ist dies die Beschreibung von “Oberbegriff partitiv” in der GND-Ontologie.

Feldsuchen

Über die <Feld>:<Suchbegriff>-Syntax kann in spezifischen Feldern gesucht werden, z.B. nach einer bestimmten Ansetzungsform:

Screenshot

http://lobid.org/gnd/search?q=preferredName:”Dom+Köln”

Will ich ein Feld abfragen, das sich nicht auf der obersten Ebene der geschachtelten JSON-Daten befindet, muss ich es über den Pfad identifizieren, das heißt ich gebe die Felder an, in denen das Feld eingebettet ist. Beispielsweise professionOrOccupation.label in folgenden Daten:

{
  "professionOrOccupation": [
    {
      "id": "http://d-nb.info/gnd/4124099-6",
      "label": "Sänger"
    }
  ]
}

So kann ich etwa nach professionOrOccupation.label:Sänger* suchen, wenn ich sowohl männliche wie auch weibliche Vokalist*innen finden möchte.

Beispiele

_exists_-Abfragen

Häufig ist es hilfreich herauszufinden, wie viele und welche Einträge überhaupt eine bestimmte Information beinhalten bzw. in wie vielen Einträgen ein bestimmtes Feld fehlt. Dafür kann eine Anfrage in der Form _exists_:<Feldname> verwendet werden, optional mit dem booleschen NOT, um alle Einträge zu bekommen, die das jeweilige nicht haben, z.B. geschlechtslose Geister:

http://lobid.org/gnd/search?q=type:Spirits+AND+NOT+_exists_:gender

Einträge mit Angabe eines Architekten

Beim Betrachten etwa des Eintrags zum Friedenspark Köln fällt auf, dass ein Architekt angegeben ist. Bei Interesse daran, welche Einträge noch Architekt*innen angeben, lässt sich das wie folgt herausfinden.

Ich schaue zunächst im JSON nach, wie das entsprechende Feld heißt:

{
  "id":"http://d-nb.info/gnd/1065252633",
  "architect":[
    {
      "id":"http://d-nb.info/gnd/118530232",
      "label":"Encke, Fritz"
    }
  ]
}

Dann schreibe ich die entsprechende _exists-Anfrage: Screenshot

Unterfelder werden wie beschrieben über eine Punkt-Notation angegeben, z.B. Architekten mit dem label “Fritz”: architect.label:Fritz

Gleichzeitige Suche in Ansetzungs- und Verweisungsformen

Aus einer E-Mail-Anfrage an das lobid-Team:

Noch eine Frage habe ich zur API. Kann ich die Suche nach Namen so einschränken, dass ich nach exakten Matches in den variantName oder preferredName suchen kann?

Das geht über eine Kombination von booleschem OR und Phrasensuche mit "<Phrase>" in den entsprechenden Feldern:

preferredName:"Muka, Arnošt" OR variantName:"Muka, Arnošt"

Im Kontext der Anzeige eines zufälligen Bildes auf der lobid-gnd-Startseite kam die Frage auf, wie viele und welche Einträge einen Wikidata-Link aber kein Bild haben. Dafür schaue ich mir zunächst am besten die Daten eines Eintrags an der beides hat, z.B. Hannah Arendt. Hier die für uns wichtigen Ausschnitte:

{
  "id":"http://d-nb.info/gnd/11850391X",
  "depiction":[
    {
      "id":"https://commons.wikimedia.org/wiki/Special:FilePath/Hannah_arendt-150x150.jpg",
      "url":"https://commons.wikimedia.org/wiki/File:Hannah_arendt-150x150.jpg?uselang=de",
      "thumbnail":"https://commons.wikimedia.org/wiki/Special:FilePath/Hannah_arendt-150x150.jpg?width=270"
    }
  ],
  "sameAs":[
    {
      "collection":{
        "abbr":"WIKIDATA",
        "name":"Wikidata",
        "publisher":"Wikimedia Foundation Inc.",
        "icon":"https://www.wikidata.org/static/favicon/wikidata.ico",
        "id":"http://www.wikidata.org/entity/Q2013"
      },
      "id":"http://www.wikidata.org/entity/Q60025"
    }
  ]
}

Die Verlinkung zu Wikidata findet sich innerhalb eines Objekts im sameAs-Array. Gekennzeichnet als Wikidata-Verlinkung ist sie durch die angegebene Sammlung (collection). Will ich also meine Suche auf Einträge einschränken, die einen Link zu Wikidata haben muss ich nach Einträgen mit der ID http://www.wikidata.org/entity/Q2013 im Feld sameAs.collection.id suchen:

sameAs.collection.id:"http://www.wikidata.org/entity/Q2013"

Hinweis: Damit die Suche funktioniert muss die Wikidata-URI (http://www.wikidata.org/entity/Q2013) in Anführungszeichen gesetzt werden (exakte Phrasensuche).

Wir wollen aber nicht alle Einträge mit Wikidata-Link, sondern nur jene ohne Bild. Das heißt wir müssen die Bedingung ergänzen, dass das Feld depiction nicht vorhanden ist. Hier kommt uns die oben eingeführte _exist_-Anfrage zur Hilfe. Konkret müssen wir zur Suchanfrage AND NOT _exists_:depiction ergänzen, so dass am Ende dabei rauskommt:

sameAs.collection.id:"http://www.wikidata.org/entity/Q2013" AND NOT _exists_:depiction

Personen, die während der NS-Zeit in Köln geboren wurden

Wenn ich eine Frage beantworten möchte wie “Welche Personen in der GND wurden in der NS-Zeit in Köln geboren?”, dann ist es sinnvoll, sich einen Eintrag zu suchen, der die nötigen Informationen zur Beantwortung einer solchen Frage besitzt. Hier z.B. die strukturierten Daten zum Eintrag von Konrad Adenauer, der folgende Informationen zu Geburtsort und -datum enthält:

{
  "id":"http://d-nb.info/gnd/11850066X",
  "placeOfBirth":[
    {
      "id":"http://d-nb.info/gnd/4031483-2",
      "label":"Köln"
    }
  ],
  "dateOfBirth":[
    "1876-01-05"
  ]
}

Den ersten Schritt – die Eingrenzung auf in Köln geborene Personen – können wir auf einfache Weise über die Benutzeroberfläche für den Eintrag von Konrad Adenauer vollziehen: Mit einem Klick auf die Lupe neben “Geburtsort Köln” wird eine Abfrage nach allen in Köln geborenen Menschen in der GND gestartet.

Screenshot

Jetzt müssen wir die vorhandene Abfrage (placeOfBirth.id:"http://d-nb.info/gnd/4031483-2") noch um eine Einschränkung des Geburtsdatums ergänzen. Hier können wir eine range query verwenden, die Zeitrahmen mit verschiedenen Detailgraden (Jahr, Monat, Tag etc.) ermöglicht. Für unseren Fall probieren wir zunächst die tagesgenaue Eingrenzung mit dateOfBirth:[1933-01-30 TO 1945-05-08]:

placeOfBirth.id:"http://d-nb.info/gnd/4031483-2" AND dateOfBirth:[1933-01-30 TO 1945-05-08]

Ebenfalls möglich ist eine jahresgenaue Abfrage (enthält hier auch Geburtsdaten im Jahr 1933 vor dem 30.1. und im Jahr 1945 nach dem 8.5.):

placeOfBirth.id:"http://d-nb.info/gnd/4031483-2" AND dateOfBirth:[1933 TO 1945]

Je nach Zweck kann die eine oder andere Abfrage sinnvoller sein.

Vollständige Query-Syntax

lobid-gnd ist auf Basis von Elasticsearch umgesetzt. Wir verweisen hier auf die vollständige Dokumentation der Elasticsearch Query String Syntax sowie der Apache Lucene Query Syntax. (Elasticsearch basiert auf Apache Lucene.)

Comments? Feedback? Just add an annotation with hypothes.is.