-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.qmd
284 lines (241 loc) · 12.3 KB
/
index.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
---
title: "Property-Graphen: eine kurze Einführung"
lang: de
date: 2024-04-24
authors:
- name: Jakob Voß
affiliation: Verbundzentrale des GBV (VZG)
affiliation-url: "https://www.gbv.de/"
citation:
type: "article"
container-title: "VZG Aktuell"
doi: "10.5281/zenodo.10971391"
volume: "2024"
issue: "1"
url: "https://jakobib.github.io/pgraphen2024/"
bibliography: references.bib
notebook-links: false
---
Zu den Tätigkeiten der Stabstelle Forschung und Entwicklung der VZG gehört auch
das Ausprobieren und Evaluieren neuer Verfahren und Techniken. So kommt es,
dass ich mich seit Anfang 2024, angeregt durch einen Anwendungsfall im Projekt
NFDI4Objects, verstärkt mit so genannten Property-Graphen zur Strukturierung
und Verarbeitung von (Meta)daten beschäftige.
Property-Graphen (oft auch *Labeled-Property-Graphen*) fallen als
Datenbankmodell unter die sogenannten NoSQL-Datenbanken, spezieller betrachtet
unter die Graphdatenbanken. Hierbei werden Daten nicht wie bei SQL in Form von
Tabellen sondern in Form von Graphen aus *Knoten* gespeichert, die durch
*Kanten* miteinander verbunden sind. Eine Besonderheit von Property-Graphen
ist, dass sowohl Knoten als auch Kanten jeweils ein oder mehrere *Labels* haben
und mit *Eigenschaften* versehen werden können.
## Beispiel
Zur Veranschaulichung soll folgende Sammlung einiger Charaktere, Beziehungen
und Eigenschaften aus dem Star-Wars-Universum dienen: Padmé, Anakin und Luke
sind Personen unterschiedlichen Geschlechts und R2D2 ist ein Roboter. In
Episode 1 gehört R2D2 zu Padmé, die ihn in Episode 2 Anakin zu ihrer
gemeinsamen Hochzeit schenkt, und in Episode 4 gelangt der Roboter zu Luke,
der in Episode 3 als Kind von Padmé und Anakin geboren wurde.
Diese Informationen lassen sich in einem Property-Graphen mit Charakteren als
Knoten und ihren Beziehungen als Kanten modellieren. @fig-image zeigt eine
mögliche Visualisierung dieses Graphen. Darin sind Knoten-Identifier fett
hervorgehoben, Labels kursiv und Eigenschaften in Festbreitenschriftart. Bis
auf die Beziehung zwischen Padmé und Anakin sind alle Kanten gerichtet.
```{mermaid}
%%| label: fig-image
%%| fig-cap: Visualisierung des Beispiel-Graphen
%%| fig-width: 100%
flowchart LR
Padme["<b>Padmé</b><br><i>person</i><br><tt>gender:female</tt>"]
Anakin["<b>Anakin</b><br><i>person</i><br><tt>gender:male</tt>"]
Luke["<b>Luke</b><br><i>person</i><br><tt>gender:male</tt>"]
R2D2["<b>R2D2</b><br><i>robot</i>"]
Padme -- "<i>owns</i><br><tt>episode:1</tt>" --> R2D2
Padme -- "<i>marriage<i><br><tt>episode:2</tt>" --- Anakin
Anakin -- "<i>owns</i><br><tt>episode:2</tt>" --> R2D2
Anakin -- "<i>child</i><br><tt>episode:3</tt>" --> Luke
Padme -- "<i>child</i><br><tt>episode:3</tt>" --> Luke
Luke -- "<i>owns</i><br><tt>episode:4</tt>" --> R2D2
```
Zur Kodierung von Property-Graphen gibt es verschiedene Datenformate und
Datenbanksysteme, die sich in Details wie den erlaubten Zeichen in Identifiern,
der Wiederholbarkeit von Labels und Eigenschaften und in möglichen Datentypen
von Eigenschaftswerten (im Beispiel Zeichenkette für die Eigenschaft `gender`
und Zahl für die Eigenschaft `episode`) unterscheiden. Im Folgenden werden zwei
mögliche Kodierungen vorgestellt und Gemeinsamkeiten und Unterschiede zum
RDF-Format erklärt.
## Property-Graph-Datenbanken
[Neo4J]: https://neo4j.com/
[Kùzu]: https://kuzudb.com/
[Memgraph]: https://memgraph.com/
[FalkorDB]: https://www.falkordb.com/
[Vendor Lock-In]: https://it-in-bibliotheken.de/management.html#vendor-lock-in
[Cypher]: https://opencypher.org/
Etabliert wurden Property-Graphen insbesondere durch das
Datenbankmanagementsystem (DBMS) [Neo4J]. Die Open-Source-Software war lange
Marktführer in diesem Bereich und setzte dort Standards wie die Abfragesprache
*Cypher* (siehe @lst-cypher und @lst-match), die inzwischen auch von anderen
Systemen unterstützt wird. Dazu zählen derzeit die Open-Source-DBMS [Kùzu],
[Memgraph] und [FalkorDB]. Im letzten Update des SQL-Standard (SQL:2023) wurde
zudem unter dem Namen SQL/PGQ eine Erweiterung für Property-Graphen in
SQL-Datenbanken definiert. Es ist also davon auszugehen, dass in Zukunft
weitere Datenbankmanagementsysteme Property-Graphen unterstützen.
Der Beispielgraph kann in Neo4J oder in einer damit kompatiblen Datenbank mit
den Cypher-Statements in @lst-cypher angelegt werden. Da Knoten-Identifier in
der Datenbank rein intern sind, sind die Namen zusätzlich als Eigenschaft
`name` angegeben. Außerdem unterstützt Cypher nur gerichtete Kanten, weshalb die Beziehung zwischen Padmé und Anakin weggelassen worden ist.
```{#lst-cypher .cypher lst-cap="Beispiel-Graph mit Cypher-Statements"}
CREATE (Anakin:person {gender:"male", name:"Anakin"})
CREATE (Luke:person {gender:"male", name:"Luke"})
CREATE (Padmé:person {gender:"female", name:"Padmé"})
CREATE (R2D2:robot {name:"R2D2"})
CREATE (Padmé)-[:owns {episode:1}]->(R2D2)
CREATE (Anakin)-[:owns {episode:2}]->(R2D2)
CREATE (Anakin)-[:child {episode:3}]->(Luke)
CREATE (Padmé)-[:child {episode:3}]->(Luke)
CREATE (Luke)-[:owns {episode:4}]->(R2D2)
```
Nun können die Daten mit Cypher-Abfragen ausgewertet werden (@lst-match):
```{#lst-match .cypher lst-cap="Abfragen in Cypher-Syntax"}
# Wer sind die Eltern der Person mit dem Namen Luke?
MATCH (p)-[:child]->(:person {name:"Luke"}) RETURN p
# Wie heißen die Besitzer von R2D2 ab Episode 2?
MATCH (p)-[e:owns]->({name:"R2D2"}) WHERE e.episode >= 2 RETURN p.name
```
Wie bei allen Datenbanken können die Abfrageergebnisse natürlich nur so gut
sein wie die Datenbasis: so würde eine Frage nach den Kindern von Anakin nur
Luke ergeben, weil seine Zwillingsschwester Leia im Beispiel-Graph fehlt.
Grundsätzlich stellt die Modellierung von Property-Graphen aber ein
leistungsfähiges und flexibels Werkzeug vor allem für semi-strukturierte und
verknüpfte Daten dar.
## Property Graph Exchange Format
Während die Standardisierung der Datenbanksprache Cypher relativ weit
fortgeschritten ist, gibt es noch kein etabliertes Dateiformat zum Austausch
von Property-Graphen. Zusammen mit den Wissenschaftlern Hirokazu Chiba, Ryota
Yamanaka und Shota Matsumoto entwickele ich deshalb das [*Property Graph
Exchange Format*](https://pg-format.github.io/specification/). @lst-pg zeigt
die Kodierung des vollständigen Beispiel-Graphen im PG-Format. Die
Standardisierung beinhaltet äquivalente Kodierungen in JSON (PG-JSON und
PG-JSONL).
```{#lst-pg .pg lst-cap="Beispiel-Graph im PG Format"}
# Knoten mit Knoten-Label und Eigenschaften
Padmé :person gender:female
Anakin :person gender:male
Luke :person gender:male
R2D2 :robot
# Kanten mit Kanten-Label und Eigenschaften
Padmé -> R2D2 :owns episode:1
Padmé -- Anakin :marriage episode:2
Anakin -> R2D2 :owns episode:2
Anakin -> Luke :child episode:3
Padmé -> Luke :child episode:3
Luke -> R2D2 :owns episode:4
```
Sie wird durch die Implementierung der Programmbibliothek
[pgraphs](https://www.npmjs.com/package/pgraphs) zur Konvertierung zwischen
verschiedenen Graph-Formaten und Datenbanksystemen begleitet. So wurde der
Beispielgraph in Neo4J in @lst-cypher automatisch mit dem Aufruf
`pgraph -t cypher -i name star-wars.pg` aus @lst-pg erzeugt.
## Vergleich mit RDF
Das *Resource Description Framework* (RDF) ist ein alternatives Graph-basiertes
Datenmodell, das zusammen mit Konzepten wie Linked Data und Semantic seit
Jahrzehnten propagiert wird. Rein formal bestehen Daten auch im RDF-Modell aus
Knoten und Kanten, wobei Knoten als "Ressourcen" und Kanten als "Triples"
bezeichnet werden. Kanten-Label heißen in RDF "Properties", Entsprechungen zu
Knoten-Label und Eigenschaften gibt dagegen nicht.
Abgesehen von formalen Unterschieden, die sich durch Datenkonvertierung
weitgehend überbrücken lassen, ist es hilfreich die unterschiedlichen
Motivationen zu verstehen, aus denen RDF und Property Graphen jeweils
entstanden sind: RDF ist grundsätzlich ein Austauschformat zum Publizieren und
Zusammenführen von Daten. Den Grundstein bilden die übergreifend nutzbaren
*Uniform Resource Identifier* (URIs) zur weltweit eindeutigen Identifizierung
von Konzepten. Bei Property-Graphen geht es dagegen primär um die effiziente
Speicherung und Auswertung von vernetzten Daten in einer abgeschlossenen
Datenbank.
Zum Vergleich zeigt @lst-ttl den Beispiel-Graphen in RDF-Turtle-Syntax und
@lst-sparql die Entsprechung der ersten Cypher-Abfrage aus @lst-match in der
RDF-eigenen Abfragesprache SPARQL. Die Rolle der Knoten-Labels und
Knoten-Eigenschaften übernehmen in RDF zusätzliche Kanten. Die
Kanten-Eigenschaften und ungerichtete Kanten sind in diesem Beispiel dagegen
weggelassen, weil ihre Entsprechung in RDF etwas komplexer zu modellieren ist.
Obwohl der RDF-Graph (@fig-rdf-image) weniger Informationen enthält, ist er im
Vergleich zu @fig-image etwas unübersichtlicher.
```{#lst-ttl .ttlr lst-cap="Beispiel-Graph in RDF/Turtle (ohne Kanten-Eigenschaften)"}
<Padmé> a <person> ; <gender> "female" .
<Anakin> a <person> ; <gender> "male" .
<Luke> a <person> ; <gender> "male" .
<R2D2> a <robot> .
<Padmé> <owns> <R2D2> .
<Anakin> <owns> <R2D2> .
<Anakin> <child> <Luke> .
<Padmé> <child> <Luke> .
<Luke> <owns> <R2D2> .
```
```{#lst-sparql .sparql lst-cap="SPARQL-Abfrage"}
# Wer sind die Eltern der Person Luke?
SELECT ?p { ?p <child> <Luke> . <Luke> a <person> }
```
```{mermaid}
%%| label: fig-rdf-image
%%| fig-cap: Visualisierung des Beispiel-Graphen in RDF
%%| fig-width: 3
flowchart LR
male([male])
female([female])
Padmé -- a --> person
Anakin -- a --> person
R2D2 -- a --> robot
Padmé -- owns --> R2D2
Anakin -- owns --> R2D2
Anakin -- child --> Luke
Padmé -- child --> Luke
Padmé -- gender --> female
Luke -- gender --> male
Anakin -- gender --> male
```
Mit der kommenden Version RDF 1.2 (auch *RDF-star*) können RDF-Triple mit
weiteren Tripeln angereichert werden, so dass eine direkte Entsprechung zu
Kanten-Eigenschaften möglich wäre (siehe @lst-ttl2 und @lst-sparql2). Abgesehen
von der begrenzten Unterstützung dieser Erweiterung in RDF-Werkzeugen werden
Daten mit RDF-star allerdings nicht unbedingt übersichtlicher.
```{#lst-ttl2 .ttlr lst-cap="Kanten des Beispiel-Graph in RDF/Turtle 1.2"}
<Padmé> <owns> <R2D2> {| <episode> 1 |} .
<Anakin> <owns> <R2D2> {| <episode> 2 |} .
<Anakin> <parent> <Luke> {| <episode> 3 |} .
<Padmé> <parent> <Luke> {| <episode> 3 |} .
<Luke> <owns> <R2D2> {| <episode> 4 |} .
```
```{#lst-sparql2 .sparql lst-cap="SPARQL 1.2 Abfrage"}
# Wer sind die Besitzer von R2D2 ab Episode 2?
SELECT ?p {
BIND( << ?p <owns> <R2D2> >> AS ?e )
FILTER ( e.episode >= 2 )
}
```
Die wesentlichen Unterschiede von RDF und Property-Graphen sind in @tbl-rdf-pg
zusammengefasst. Grundsätzlich ist RDF vor allem für die Zusammenführung von
Daten aus unterschiedlichen Quellen sinnvoll. RDF-Daten werden daher
tendenziell eher projektübergreifend und nachnutzbar angelegt. Dieser Vorteil
birgt in der Praxis allerdings auch die Gefahr von langwierigen Prozessen und
theoretischen, komplexeren Lösungen.
RDF | Property Graphen
----------------|------------------
Graph aus Knoten und Kanten | Graph aus Knoten, Kanten und Eigenschaften
Etabliert durch das W3C | Standardisierung noch nicht abgeschlossen
Identifier sind globale URIs | Interne oder lokale Knoten-Identifier
Globale Ontologien und Regeln | Lokale Datenbank-Schemas
Abfragesprache SPARQL | Abfragesprache Cypher
: RDF und Property-Graphen im Vergleich {#tbl-rdf-pg}
## Property Graphen an der VZG
An der VZG werden Property-Graphen vor allem im Projekt
[NFDI4Objects](https://www.nfdi4objects.net/) eingesetzt. Darüber hinaus sollen
Sacherschließungsdaten des K10plus für Analysen in einer Graphdatenbank
indexiert werden. In beiden Fällen ist das Ergebnis ein sogenannter *Knowledge
Graph*. Für die Integration mit anderen Datenquellen sollen beide Knowledge
Graphen auch in RDF bereitgestellt und RDF-Daten durch Konvertierung in das
PG-Format mit Property-Graphen zusammengeführt werden.
## Zusammenfassung
Property-Graphen bilden ein flexibles und nicht zu kompliziertes Werkzeug zur
Strukturierung, Speicherung und Auswertung vernetzter Daten. Im Gegensatz zu
RDF sind Property Graphen allerdings nicht als allgemeines Austauschformat
gedacht. Die VZG setzt Property-Graphen für Datenanalysen ein und ist an der
laufenden Standardisierung beteiligt.