MARC21xml-Daten (GND, ZDB, bibliographische Metadaten von DNB und SBB) und EAD-Daten (Kalliope-Verbund) werden in GraphML transformiert und anschließend in Neo4j geladen. Informationen zum Datenbezug:
- Gemeinsame Normdatei: https://data.dnb.de/GND/
- Zeitschriftendatenbank: https://data.dnb.de/ZDB/
- DNB-Titeldaten: https://data.dnb.de/DNB/
- SBB-Titeldaten: https://lab.sbb.berlin/bibliographische-daten-aus-dem-stabikat/
- Kalliope-Verbund: https://lab.sbb.berlin/kpe/
Die Datentransformation gliedert sich grob in drei Schritte:
- Schritt 1: Daten müssen transformiert werden. Output: Mehrere, (noch) nicht valide GRAPHML Dateien, aufgeteilt jeweils in Knoten und Kanten
- Schritt 2: Transformierte Daten müssen zusammengeführt werden. Output: EINE valide GRAPHML Datei, erstellt aus den aus Schritt 1 transformierten Dateien (+ Isil Nodes)
- Schritt 3: Aus der zusammengeführten Datei muss das Sonderzeichen "&" escaped werden (
replace_spec_char()
inmerge.py
), um Import Error zu vermeiden. Output: EINE valide GRAPHML Datei ohne alleinstehende "&" (Schritt 3 sollte in Zukunft in einer der vorherigen Schritte integriert werden)
Im Folgenden wird dargestellt, welche Funktionen wie genutzt werden können und welche Schritte damit erfüllt werden.
Um alle Daten (ausgenommen OCR Daten) zu transformieren, im Terminal folgendes ausführen:
python trs.py
Achtung: Vor dem Ausführen müssen die Pfade in trs.py zu den Datendumps angepasst werden!
Um alle Daten inklusive OCR Daten zu transformieren und anschließend zusammen mit allen Daten in eine GRAPHML Datei zusammenzuführen, im Terminal folgendes ausführen:
python trs.py integrate_ocr ocr_tsv_dir/ merged/output_filename.graphml ocr_data_dir/ all_data_dir/
Achtung: Vor dem Ausführen müssen die Pfade in trs.py zu den Datendumps angepasst werden!
Argumente der integrate_ocr
Funktion:
- ocr_tsv_dir/: Ordner, welcher die OCR Daten im TSV Format enthält
- merged/output_filename.graphml: Name und Ort der finalen zusammengeführten GRAPHML Datei. Diese Datei enthält alle SoNAR Daten.
- ocr_data_dir/: Ordner, welcher nur die OCR .graphml Dateien enthält (DocContainsEntEdges.graphml, OCRDocumentNodes.graphml, SameAsEdges.graphml, WikiNodes.graphml)
- all_data_dir/: Ordner, welcher alle anderen .graphml Dateien enthält, außer die OCR GRAPHML Dateien.
cd enrich
python transform_ocr.py process_tsv path_to_tsv/ path_to/entities-dict.json
Argumente der process_tsv
Funktion:
- path_to_tsv: Ordner, welcher die OCR Daten im TSV Format enthält
- path_to/entities-dict.json: Name und Ort der JSON Datei.
cd enrich
python transform_ocr.py write_enriched_graphml path_to/entities-dict.json path_to_ocr_graphml/ out_format
Argumente der write_enriched_graphml
Funktion:
- path_to/entities-dict.json: Name und Ort der JSON Datei.
- path_to_ocr_graphml/: Ort, an dem die GRAPHML OCR Dateien gespeichert werden sollen
- out_format : Momentan nur "graphml" als Wert möglich
cd enrich
python merge.py merge_except_ocr path_to/merged_filenname.graphml path_to_graphml_files/
Argumente der merge_except_ocr
Funktion:
- path_to/merged_filenname.graphml: Name und Ort der zu erstellenden Datei
- path_to_graphml_files/: Ort der GRAPHML Dateien
cd enrich
python merge.py merge_all_files path_to/merged_filenname.graphml path_to_ocr_graphml_files/ path_to_other_graphml_files/
Argumente der merge_except_ocr
Funktion:
- path_to/merged_filenname.graphml: Name und Ort der zu erstellenden Datei
- path_to_ocr_graphml_files/: Ort der OCR GRAPHML Dateien
- path_to_other_graphml_files/: Ort der anderen GRAPHML Dateien
cd enrich
python merge.py replace_spec_char path_to/merged_filenname.graphml path_to/replaced_char_in_merged.graphml
Argumente der replace_spec_char
Funktion:
- path_to/merged_filenname.graphml: Name und Ort der zusammengeführten Datei aus Schritt 2
- path_to/replaced_char_in_merged.graphml: Name und Ort der zusammengeführten Datei ohne alleinstehendes "&"
- Pfad zu Ordner mit Ausgangsdaten in Terminal eingeben
- Ausgabe, wenn Skripts ausgeführt werden, optimieren
- Konflikt in EadTransform.py line 56 beim Einlesen des Zip-Files, so steht z.Z. da ein String statt einer Variable 'filename'
requirements
hinzufügenUML-Modell erstellen, was neo4j generiert ist unübersichtlich
Zu beachten, dass Pfade zu Ausgangsdaten in trs.py
geändert werden müssen.
Eingabeformat: MARC21
Ausgabeformat: JSON, GRAPHML
Optionen:
dataType={'Authority', 'Bibliographic'}
. Der Datentyp'Authority'
entspricht Normdaten, der Datentyp'Bibliographic'
- Metadaten;dataType='Authority'
ist in Kombination mitentityType={"PerName", "CorpName", "MeetName", "UniTitle", "TopicTerm", "GeoName"}
möglich;dataType='Bibliographic'
ist in Kombination mitentityType={"Zdb", "Dnb1", "Dnb2", "Dnb3", "Dnb4"}
möglich;entityType={"PerName", "CorpName", "MeetName", "UniTitle", "TopicTerm", "GeoName", "Zdb", "Dnb1", "Dnb2", "Dnb3", "Dnb4"}
;dataSelection={True, False}
;outputFormat={"json", "graphml"}
:outputFormat="graphml"
ist nur in Kombination mitdataSelection=True
möglich
Transformierte Daten werden in data
gespeichert
Liste der gefundenen Duplikate s. in src/dublesBibliographicRecords.txt
Gilt für Transformation zu GRAPHML
Gleiche Ressourcen (bezüglich Identifikatoren), die in der DNB und ZDB vorkommen, sind gefiltert und als eine Ressource dargestellt (s. Dubletten aus der DNB und ZDB, Stand 2019). Zu beachten, dass Dubletten aus der DNB und SBB nicht ausgefiltert wurden, weil diese mit verschiedenen internen Identifikatoren (DE-101 für DNB und DE-599 für SBB) versehen sind.
Es gibt Fehlermeldungen, die in log
geschrieben werden, wenn folgende Inkonsistenzen gefunden werden:
-
- Felder mit fehlenden Identifikatoren, Namen oder Titeln;
-
- Invalide Codes;
-
- Veraltete Identifikatoren in Feldern 5XX .
Beispiele der Fehlermeldungen s. in log/Readme.md
.
Es wird geprüft, ob es für einen Record Informationen zu Identifikator, Namen bzw. Titel existieren. Meldungen werden in log
gespeichert, Datensätze bei der Transformation werden nicht geändert.
<datafield tag="110" ind1="2" ind2=" ">
<subfield code="b">Saint-Avold en Moselle</subfield>
</datafield>
In Daten können sich sowohl Unterfelder, als auch Felder komplett wiederholen. Dies betrifft einen Unterfeld mit der Code "g" im folgenden Beispiel, der zweimal vorkommt:
<datafield tag="551" ind1=" " ind2=" ">
<subfield code="0">(DE-101)042567238</subfield>
<subfield code="0">(DE-588)4256723-3</subfield>
<subfield code="0">https://d-nb.info/gnd/4256723-3</subfield>
<subfield code="a">Langer Gang</subfield>
<subfield code="g">Dresden</subfield> <!-------Vorkommen Nr. 1----->
<subfield code="g">Dresden</subfield> <!-------Vorkommen Nr. 2----->
<subfield code="4">ortb</subfield>
<subfield code="4">https://d-nb.info/standards/elementset/gnd#placeOfCustody</subfield>
<subfield code="w">r</subfield>
<subfield code="i">Aufbewahrungsort</subfield>
</datafield>
Im nächsten Beispiel kommt ein Feld 400 zweimal, wobei unterschiedliche Unterfelder mit entsprechenden Codes sowie beide Indikatoren gleiche Information enthalten. Dies betrifft eine Person mit dem Vornamen (ind1="0") "Xenophon" (code="a"), Datumsangaben "ca. 430 v.Chr.-354 v. Chr." (code="d"), einen Titel "Athēnaiōn politeia" (code="t").
...
<!-------Vorkommen Nr. 1---------------------------------->
<datafield tag="400" ind1="0" ind2=" ">
<subfield code="a">Xenophon</subfield>
<subfield code="d">ca. 430 v.Chr.-354 v. Chr.</subfield>
<subfield code="t">Athēnaiōn politeia</subfield>
</datafield>
<!------------------------------------------------------->
<datafield tag="400" ind1="0" ind2=" ">
<subfield code="a">Xenophon</subfield>
<subfield code="d">ca. 430 v.Chr.-354 v. Chr.</subfield>
<subfield code="t">Staatsverfassung der Athener</subfield>
</datafield>
...
<!-------Vorkommen Nr. 2--------------------------------->
<datafield tag="400" ind1="0" ind2=" ">
<subfield code="a">Xenophon</subfield>
<subfield code="d">ca. 430 v.Chr.-354 v. Chr.</subfield>
<subfield code="t">Athēnaiōn politeia</subfield>
</datafield>
<!------------------------------------------------------->
Repetitive Felder bei der Transformation zu JSON, GRAPHML werden ignoriert. Transformiert wird das erste Vorkommen. Letztes Bespiel sieht in JSON folgend aus:
[
...,
{
"a": [
"Xenophon"
],
"d": [
"ca. 430 v.Chr.-354 v. Chr."
],
"t": [
"Athēnaiōn politeia"
],
"ind1": "0",
"ind2": " "
},
{
"a": [
"Xenophon"
],
"d": [
"ca. 430 v.Chr.-354 v. Chr."
],
"t": [
"Staatsverfassung der Athener"
],
"ind1": "0",
"ind2": " "
},
...
]
Es werden folgende Codes geprüft und Meldungen über Fehler in log
gespeichert. Codes in Daten werden nicht geändert!
- Satztypen der GND (gndgen)
- Untersatztypen der GND (gndspec)
<datafield tag="075" ind1=" " ind2=" ">
<subfield code="b">saw</subfield>
<subfield code="2">gndspec</subfield>
</datafield>
- Ländercodes nach ISO 3166
- GND-Codes für die Art der Beziehung (Entity)
- Codes für Relators (Resource)
Gültige Codes aus MARC21 s. in src/MARC21Codes.py
Gilt für Transformation zu GRAPHML
Veraltete Identifikatoren, die in Feldern 5XX gefunden werden, werden bei der Transformation zu GRAPHML durch aktuelle Identifikatoren ersetzt. Relationen mit fehlenden, nicht eindeutigen Identifikatoren bzw. ohne Identifikatoren (wieder in Feldern 5XX) werden ignoriert, also keine Verknüpfungen zu in Feldern 1XX/245 beschriebenen Entitäten/Ressourcen hergestellt.
a) Entitäten mit veralteten Identifikatoren (betrifft nur GND-Entitäten, kann man aber bei allen Quellen, wo Relationen beschrieben sind, finden)
Veraltete Identifikatoren werden durch aktuelle ersetzt, um entsprechende Entitäten/Ressourcen angemessen zu verknüpfen. Eine Liste der veralteten und neuen Identifikatoren findet man in (s. in src/AllOldAuthorityIdentifier.py
).
Es gibt 4.185.374 Datensätze in der GND, die in unseren Daten fehlen. Es geht um Tn-Datensätze (nur Namensansetzungen). Diese Daten sind für SoNAR, so GM, nicht bedeutend, da die Datensätze nicht eine Entität (Person), sondern einen Namen diverser Entitäten (Personen) beschreiben. Somit werden keine Verknüpfungen zu diesen Entitäten hergestellt. Ihre Ids findet man in src/nonEntities.txt
.
Via neo4j werden nicht eindeutige veralteten Identifikatoren gefunden, die zwei neuen Identifikatoren entsprechen. Sie werden zu src/nonEntities.txt
hinzugefügt, weil ihre Zuordnung zu neuen Identifikatoren widersprüchlich ist.
- Veraltete ID (neue ID1, neue ID2)
- 122945662 (10211787X, 118693484)
- 1059225026 (1027146961, 1061213641)
- 4196845-1 (2086834-0, 2142242-4)
- 4100306-8 (2065029-2, 4549912-3)
Bei der Transformation zu GRAPHML werden Relationen zu Entitäten ohne Identifikatoren ignoriert. Eine angemessene Zuordnung dieser Entitäten zu GND-Entitäten ist nun manuell möglich.
Eingabeformat: EAD
Ausgabeformat: JSON, GRAPHML
Optionen:
dataType={'Bibliographic'}
. Der Datentyp'Authority'
entspricht Normdaten, der Datentyp'Bibliographic'
- Metadaten;Wenn Transformation als eine Pipeline (zusammen mit Transformation MARC21) eingesetzt wird, dann kommt das MerkmaldataType='Bibliographic'
ist in Kombination mitentityType={"Kpe"}
möglich;entityType="Kpe"
ins SpieldataSelection={True, False}
;outputFormat={"json", "graphml"}
:outputFormat="graphml"
ist nur in Kombination mitdataSelection=True
möglich
Gilt für Transformation zu GRAPHML
Es findet gleiche Konsistenzprüfung wie bei MARC21 statt. Es gibt Fehlermeldungen, die in log
geschrieben werden, wenn folgende Inkonsistenzen gefunden werden:
-
- Felder mit fehlenden Identifikatoren, Namen oder Titeln;
-
- Veraltete Identifikatoren bei Relationen.