Nachträge Kapitel 7
This commit is contained in:
parent
d0bca71bff
commit
f2ea383b2c
|
@ -1,56 +1,153 @@
|
||||||
# 7.6 Felder definieren
|
# 7.6 Felder definieren
|
||||||
|
|
||||||
Jetzt wird es konkret: Welche Informationen wollen Sie in Ihrem Bibliothekskatalog anbieten? Welche Kurzinformationen sollen in der Trefferliste stehen? Welche Informationen sollen in der Vollanzeige dargestellt werden? Im Suchindex wird alles in Feldern abgelegt, die später im Relevanzranking auch gewichtet werden können. In der Software zur Anzeige (TYPO3-find in unserem Fall), können Sie auch später noch mehrere Felder kombiniert darstellen.
|
Jetzt wird es konkret: Welche Informationen wollen Sie in Ihrem Bibliothekskatalog anbieten? Welche Kurzinformationen sollen in der Trefferliste stehen? Welche Informationen sollen in der Vollanzeige dargestellt werden? Wir bilden jetzt aus den Rohdaten die gewünschten Felder.
|
||||||
|
|
||||||
## Aufgabe 1: Identifizieren Sie wichtige Felder wie Titel, Autor/in, Ort, Erscheinungsjahr, Medientyp in den MARC-Daten
|
Für alle folgenden Arbeiten in OpenRefine können Sie die Version 2.6rc2 verwenden:
|
||||||
|
|
||||||
Hinweise:
|
```
|
||||||
|
sudo docker run --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc2 -i 0.0.0.0 -m 3G -d /data
|
||||||
* Wenn Sie im [OPAC der HAW Hamburg](https://kataloge.uni-hamburg.de/LNG=DU/DB=2/) in die Suche ```PPN .?``` eingeben, dann erhalten Sie alle rund 450.000 Treffer. Über den Menüpunkt Trefferanalyse können Sie sich dann einen groben Überblick über die enthaltenen Daten verschaffen. Mit der Suche können Sie auch direkt einzelne Datensätze aufrufen. Beispiel: ```PPN 834422018```.
|
```
|
||||||
* Nutzen Sie die [Arbeitstabelle der Deutschen Nationalbibliothek](http://www.dnb.de/SharedDocs/Downloads/DE/DNB/standardisierung/marc21FeldbeschreibungTitelExcel032016.zip) in der [Dokumentation des MARC21-Formats](http://www.dnb.de/DE/Standardisierung/Formate/MARC21/marc21_node.html), um die MARC-Felder zu übersetzen.
|
|
||||||
* Der Suchindex erwartet eine eindeutige Kennung (Identifier) in der ersten Spalte. Prüfen Sie, ob Sie eine vorhandene Nummer dafür verwenden können.
|
|
||||||
|
|
||||||
## Lösung
|
|
||||||
|
|
||||||
Hier gibt es keine allgemeingültige Lösung. Jetzt ist es an Ihnen, Ihren Katalog so zu gestalten, wie Sie ihn haben wollen. Notieren Sie sich zunächst die MARC-Felder, die besonders relevant oder interessant für Sie sind.
|
|
||||||
|
|
||||||
## Aufgabe 2: Bilden Sie neue Felder (bzw. Spalten) durch die Kombination von verschiedenen Feldern
|
|
||||||
|
|
||||||
Hinweise:
|
|
||||||
|
|
||||||
* Wenn Sie nicht wissen, wo Sie beginnen sollen, dann versuchen Sie zunächst mit einem kleinen Satz von Feldern anzufangen. In Kapitel 4 haben Sie das Format Dublin Core als einen "kleinsten gemeinsamen Nenner" kennengelernt. Sie können damit beginnen diese Felder zu bilden. Die Library of Congress hat einen [Crosswalk von MARC21 zu Dublin Core](http://www.loc.gov/marc/marc2dc.html) bereitgestellt, den Sie zur Orientierung nutzen können.
|
|
||||||
|
|
||||||
<!---
|
|
||||||
|
|
||||||
## Lösung
|
|
||||||
|
|
||||||
Vorgehen für Felder, die im Crosswalk von MARC21 zu Dublin Core (unqualified) genannt sind:
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
**Als JSON-Datei: [07_6-2.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-2.json)**
|
|
||||||
|
|
||||||
--->
|
|
||||||
|
|
||||||
## Aufgabe 3: Daten bereinigen
|
|
||||||
|
|
||||||
Hinweise:
|
|
||||||
|
|
||||||
* Prüfen Sie, ob in den Feldern noch unerwünschte Zeichen vorkommen, die nicht im Suchindex landen sollen.
|
|
||||||
* Versuchen Sie außerdem Datumsangaben mit der Funktion ```toDate()``` in maschinenlesbare Datumsformate nach ISO-8601 zu wandeln.
|
|
||||||
* Der Suchindex erwartet eine eindeutige Identifikationsnummer in der ersten Spalte. Das Feld wird üblicherweise ```id``` benannt. Benennen Sie die Spalte mit dem MARC-Feld ```001``` in ```id``` um und verschieben Sie diese in die erste Spalte (falls Sie dort nicht ohnehin stehen sollte).
|
|
||||||
|
|
||||||
<!---
|
|
||||||
|
|
||||||
## Lösung (für die Felder aus Lösung Aufgabe 2)
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
** Als JSON-Datei (für die Felder aus Lösung Aufgabe 2): [07_6-3.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-3.json)****
|
|
||||||
|
|
||||||
--->
|
|
||||||
|
|
||||||
## Literatur
|
## Literatur
|
||||||
|
|
||||||
* Owen Stephens: [A worked example of fixing problem MARC data: Part 4 – OpenRefine](http://www.meanboyfriend.com/overdue_ideas/2015/07/worked-example-fixing-marc-data-4/)
|
* Owen Stephens: [A worked example of fixing problem MARC data: Part 4 – OpenRefine](http://www.meanboyfriend.com/overdue_ideas/2015/07/worked-example-fixing-marc-data-4/)
|
||||||
* Library Carpentry OpenRefine: [Basic OpenRefine functions II](https://data-lessons.github.io/library-openrefine/04-basic-functions-II/)
|
* Library Carpentry OpenRefine: [Basic OpenRefine functions II](https://data-lessons.github.io/library-openrefine/04-basic-functions-II/)
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 1: Prüfen, wie häufig Felder belegt sind
|
||||||
|
|
||||||
|
Sie können sich mit den Facetten in OpenRefine einen Überblick über die Belegung der Spalten verschaffen. Wählen Sie dazu ```Facet -> Customized facets -> Facet by blank```.
|
||||||
|
|
||||||
|
Da dies bei den vielen enthaltenen Spalten recht mühsam ist, können Sie alternativ die TSV-Dateien auch auf der Kommandozeile durchzählen.
|
||||||
|
|
||||||
|
### Vorgehen
|
||||||
|
|
||||||
|
**1. Projekt als TSV exportieren**
|
||||||
|
|
||||||
|
Das im vorigen Kapitel erstellte Gesamtprojekt wie gewohnt als TSV exportieren (vgl. [Kapitel 7.5](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/07_5_alle_daten_in_ein_projekt_laden.html), Aufgabe 4).
|
||||||
|
|
||||||
|
**2. TSV-Datei auf Server hochladen**
|
||||||
|
|
||||||
|
Die exportierte TSV-Datei in das Verzeichnis ```tsv``` auf den Webserver laden (vgl. [Kapitel 7.5](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/07_5_alle_daten_in_ein_projekt_laden.html), Aufgabe 5).
|
||||||
|
|
||||||
|
**3. Script ausführen**
|
||||||
|
|
||||||
|
* Script mit ```curl``` auf den Server laden: ```curl -O https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/count-tsv.sh```
|
||||||
|
* Script ausführbar machen: ```chmod +x count-tsv.sh```
|
||||||
|
* Script starten mit ```./count-tsv.sh ~/tsv/haw-komplett.tsv | tee felder.tsv```
|
||||||
|
|
||||||
|
### Ergebnis
|
||||||
|
|
||||||
|
Das Script gibt Ihnen nach und nach die Belegung aller enthaltenen Felder aus. Sie werden feststellen, dass viele Felder kaum belegt sind. Die dritte Spalte gibt an, wie häufig das Feld mehrfachbelegt ist (d.h. wie häufig das Zeichen ```␟``` vorkommt, das wir in Kapitel 7.3, Schritt 7 als Trennzeichen für mehrfach belegte Felder festgelegt haben).
|
||||||
|
|
||||||
|
Der letzte Teil des Befehls (```tee felder.tsv```) sorgt dafür, dass zusätzlich zu der Ausgabe auf der Kommandozeile die Ergebnisse in der Datei "felder.tsv" gespeichert wurden.
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 2: Datei felder.tsv in Tabellenverarbeitung (Excel/LibreCalc) öffnen
|
||||||
|
|
||||||
|
Laden Sie die Datei felder.tsv auf ihren Rechner und öffnen Sie diese in einem Tabellenverarbeitungsprogramm (Microsoft Excel oder LibreOffice Calc). Falls beim Öffnen ein Dialog erscheint, geben Sie an, dass die Zellen mit "Tab" getrennt sind.
|
||||||
|
|
||||||
|
Sortieren Sie die Tabelle nach Spalte "Vorkommen" aufsteigend. Bei über 440.000 Datensätzen können wir vermutlich diejenigen Felder vernachlässigen, die weniger als 10x belegt sind. Löschen Sie diese Spalten in OpenRefine.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* Datei felder.tsv herunterladen (vgl. [Kapitel 6.3](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/06_3_openrefine_starten_und_daten_laden.html), Aufgabe 1)
|
||||||
|
* Löschen der Spalten mit weniger als 10 Vorkommen in OpenRefine: Menü oben links "Undo / Redo" aufrufen und Button "Apply..." drücken. Den Inhalt aus der Datei [07_6-2.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-2.json) in die Zwischenablage kopieren und in das Textfeld von "Apply" einfügen und Button "Perform Operations" drücken.
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 3: Identifizieren Sie wichtige Felder wie Titel, Urheber, Ort, Erscheinungsjahr, Medientyp in den MARC-Daten
|
||||||
|
|
||||||
|
Notieren Sie Ihre Erkenntnisse zunächst in der Tabelle felder.tsv.
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
|
||||||
|
* Wenn Sie im [OPAC der HAW Hamburg](https://kataloge.uni-hamburg.de/LNG=DU/DB=2/) in die Suche ```PPN .?``` eingeben, dann erhalten Sie alle rund 450.000 Treffer. Über den Menüpunkt Trefferanalyse können Sie sich dann einen groben Überblick über die enthaltenen Daten verschaffen. Mit der Suche können Sie auch direkt einzelne Datensätze aufrufen. Beispiel: ```PPN 834422018```.
|
||||||
|
* Wenn Sie nicht wissen, wo Sie beginnen sollen, dann versuchen Sie zunächst mit einem kleinen Satz von Feldern anzufangen. In Kapitel 4 haben Sie das Format Dublin Core als einen "kleinsten gemeinsamen Nenner" kennengelernt. Sie können damit beginnen, diese Felder zu bilden. Die Library of Congress hat einen [Crosswalk von MARC21 zu Dublin Core](http://www.loc.gov/marc/marc2dc.html) bereitgestellt, den Sie zur Orientierung nutzen können.
|
||||||
|
* Nutzen Sie zusätzlich die [Arbeitstabelle der Deutschen Nationalbibliothek](http://www.dnb.de/SharedDocs/Downloads/DE/DNB/standardisierung/marc21FeldbeschreibungTitelExcel032016.zip) in der [Dokumentation des MARC21-Formats](http://www.dnb.de/DE/Standardisierung/Formate/MARC21/marc21_node.html), um die MARC-Felder zu übersetzen.
|
||||||
|
* Der Suchindex erwartet eine eindeutige Kennung (Identifier) in der ersten Spalte. Prüfen Sie, ob Sie eine vorhandene Nummer dafür verwenden können.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* Hier gibt es keine allgemeingültige perfekte Lösung. Vergleichen Sie Ihre Erkenntnisse mit der folgenden unvollständigen Empfehlung: [felder.tsv](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/felder.tsv)**
|
||||||
|
* Diese unvollständige Empfehlung bildet auch die Grundlage für die folgenden Aufgaben. Diese haben nicht zum Ziel ein perfektes Mapping zu erstellen, sondern sollen ein paar Problemfelder illustrieren und sinnvolle Beispieldaten für den Suchindex (Kapitel 8) und die Kataloganzeige (Kapitel 9) bilden.
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 4: Bilden Sie in OpenRefine das Feld "Titel" durch die Kombination verschiedener MARC-Felder
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
|
||||||
|
* Die Expression zur Kombination von mehreren Feldern lautet (am Beispiel der Spalten 245 : a und 245 : b): ```cells["245 : a"].value + cells["245 : b"].value```. Die Werte der Zellen werden also schlicht mit einem ```+``` verbunden.
|
||||||
|
* Leider schlägt diese Expression fehl, wenn die zu ergänzende Zelle leer ist. Daher muss eine if-Abfrage ergänzt werden, damit die Transformation nur für nicht-leere Zellen durchgeführt wird: ```cells["245 : a"].value + if(isNonBlank(cells["245 : b"].value,cells["245 : b"].value,"")```
|
||||||
|
* Üblicherweise werden die Bestandteile des Titels durch unterschiedliche Trennzeichen getrennt. Die Trennzeichen sollten allerdings nur ergänzt werden, wenn danach auch ein Wert folgt. Daher muss die Ergänzung des Trennzeichens mit einer if-Abfrage von der folgenden Zelle abhängig gemacht werden. Beispiel für 245 : a und 245 : b mit Trennzeichen: ```cells["245 : a"].value + if(isNonBlank(cells["245 : b"].value),". ","") + if(isNonBlank(cells["245 : b"].value),cells["245 : b"].value,"")
|
||||||
|
* Probieren Sie auf diese Weise alle relevanten MARC-Felder zu einem Titel-Feld zu kombinieren.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* {%s%}Spalte "245 : a" / Edit column / Add column based on this column...{%ends%}
|
||||||
|
* {%s%}New column name: Titel{%ends%}
|
||||||
|
* {%s%}Expression: value + if(isNonBlank(cells["245 : b"].value),". ","") + if(isNonBlank(cells["245 : b"].value),cells["245 : b"].value,"") + if(isNonBlank(cells["245 : n"].value)," - ","") + if(isNonBlank(cells["245 : n"].value),cells["245 : n"].value,"") + if(isNonBlank(cells["245 : p"].value)," - ","") + if(isNonBlank(cells["245 : p"].value),cells["245 : p"].value,"") + if(isNonBlank(cells["246 : a"].value)," - ","") + if(isNonBlank(cells["246 : a"].value),cells["246 : a"].value,""){%ends%}
|
||||||
|
|
||||||
|
**Als JSON-Datei: [07_6-4.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-4.json)**
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 5: Löschen Sie alle Datensätze, in denen das Feld "Titel" nicht belegt ist
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
|
||||||
|
* In den ca. 440.000 Datensätzen sind viele Fremd- und Normdaten enthalten, die wir zunächst nicht berücksichtigen wollen, um es nicht zu kompliziert zu machen.
|
||||||
|
* Vereinfachend lässt sich annehmen, dass alle Datensätze, die nach Erledigung der Aufgabe 4 noch keinen Titel haben, gelöscht werden können.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* {%s%}Spalte "Titel" / Facet / Customized facets / Facet by blank / true{%ends%}
|
||||||
|
* {%s%}All / Edit rows / Remove all matching rows{%ends%}
|
||||||
|
* {%s%}Facette schließen{%ends%}
|
||||||
|
|
||||||
|
** Als JSON-Datei: [07_6-5.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-5.json)**
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 6: Generieren Sie einheitliche ISBN-Nummern mit 13 Ziffern
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
|
||||||
|
* Im MARC-Feld "020 : a" stehen teilweise 10-stellige, teilweise 13-stellige ISBN-Nummern.
|
||||||
|
* Suchen Sie nach einem Weg, um diese auf 13 Ziffern zu vereinheitlichen.
|
||||||
|
* Da es hier viele Mehrfachbelegungen gibt, müssen Sie die Zellen zunächst aufsplitten und nach erledigter Transformation wieder zusammenführen. Dieser Prozess ist speicherintensiv, also starten Sie OpenRefine vor und nach dieser Aufgabe besser neu.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* {%s%}Spalte "020 : a" / Edit cells / Split multi-valued cells... / ␟{%ends%}
|
||||||
|
* {%s%}Spalte "020 : a" / Facet / Custom text facet... / Expression: value.length() / 13{%ends%}
|
||||||
|
* {%s%}Spalte "020 : a" / Edit column / Add column based on this column... / New column name: ISBN /Expression: value{%ends%}
|
||||||
|
* {%s%}Spalte "020 : a" / Facet / Custom text facet... / Expression: value.length() / 10{%ends%}
|
||||||
|
* {%s%}Spalte "ISBN" / Edit cells / Transform... / Expression: with('978'+cells["020 : a"].value[0,9],v,v+((10-(sum(forRange(0,12,1,i,toNumber(v[i])*(1+(i%2*2)) )) %10)) %10).toString()[0] ){%ends%}
|
||||||
|
* {%s%}Facette schließen{%ends%}
|
||||||
|
* {%s%}Spalte "ISBN" / Edit cells / Join multi-valued cells... / ␟{%ends%}
|
||||||
|
* {%s%}Spalte "020 : a" / Edit cells / Join multi-valued cells... / ␟{%ends%}
|
||||||
|
|
||||||
|
Anmerkung: Alle Sonderfälle, in denen noch Text hinter den ISBN-Nummern steht, sind mit diesen Transformationsregeln noch nicht behandelt. Dafür liegt aber zumindest für einen Teil der Datensätze eine einheitliche ISBN13-Kodierung vor.
|
||||||
|
|
||||||
|
** Als JSON-Datei: [07_6-6.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-6.json)**
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 7: Ergänzen Sie ein Feld "id" für den Suchindex
|
||||||
|
|
||||||
|
Der Suchindex Solr erwartet ein Feld "id" mit eindeutiger Kennung in der ersten Spalte.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* {%s%}Spalte "001" / Edit column / Add column based on this column... / New column name: id{%ends%}
|
||||||
|
|
||||||
|
** Als JSON-Datei: [07_6-7.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-7.json)**
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 8: Wenden Sie die vorbereitete Transformationsdatei zur Generierung weiterer Felder an
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
|
||||||
|
* Verwenden Sie die **JSON-Datei [07_6-8.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_6-8.json)**, die Transformationsregeln zur Generierung weiterer Felder auf Basis der Empfehlung aus Aufgabe 3 enthält.
|
||||||
|
|
||||||
|
## Lösung
|
||||||
|
|
||||||
|
* {%s%}Menü oben links "Undo / Redo" aufrufen und Button "Apply..." drücken {%ends%}
|
||||||
|
* {%s%}Den Inhalt aus der Datei 07_6-8.json (siehe Link oben) in die Zwischenablage kopieren und in das Textfeld von "Apply" einfügen und Button "Perform Operations" drücken{%ends%}
|
|
@ -4,15 +4,17 @@ OpenRefine bietet viele Möglichkeiten die Daten in verschiedene Formate zu expo
|
||||||
|
|
||||||
Hinweise:
|
Hinweise:
|
||||||
|
|
||||||
* Der Klick auf den Menüpunkt Export / TSV startet sofort einen Download der Daten. Das reicht in den meisten Fällen aus. Probieren Sie aber auch die anderen Möglichkeiten aus.
|
* Der Klick auf den Menüpunkt "Export / Tab-separated value" startet sofort einen Download der Daten. Dabei werden jedoch alle Spalten exportiert. Nutzen Sie stattdessen "Export / Custom tabular exporter..." und wählen Sie nur die in Kapitel 7.6 generierten Felder aus.
|
||||||
* Wenn Sie die Daten exportiert haben, können Sie folgende Befehle zur Überprüfung der Daten verwenden: ```wc -l -c``` und ```head -n1```
|
* Benennen Sie die Datei in "haw-prozessiert.tsv" um und laden Sie sie auf den Webserver in den Ordner ~/tsv.
|
||||||
|
* Wenn Sie die Daten exportiert haben, können Sie folgende Befehle zur Überprüfung der Daten verwenden: ```wc -l``` und ```head -n1```.
|
||||||
|
|
||||||
## Lösung
|
## Lösung
|
||||||
|
|
||||||
* Export: {%s%}Projekte nacheinander in OpenRefine laden und im Menü oben rechts Export / "Tab separated value" wählen. Der Download sollte automatisch beginnen. Speichern Sie die Daten lokal in einem beliebigen Verzeichnis.{%ends%}
|
* Export: {%s%}Projekt in OpenRefine laden und im Menü oben rechts Export / Custom tabular exporter... auswählen. Dann Button "De-select All" klicken und nur die Felder auswählen, die in Kapitel 7.6 angelegt wurden: id, ISBN, ISSN, Sprache, LCC, DDC, Urheber, Medientyp, Ort, Verlag, Jahr, Datum, Beschreibung, Schlagwoerter, Beitragende, Reihe, Vorgaenger, Nachfolger, Link, Titel. Anschließend im Reiter Download auf den Download-Button klicken.{%ends%}
|
||||||
* Zählung der Zeilen der TSV-Dateien (sollte der Anzahl der Records minus 1 entsprechen): {%s%}wc -l -c *.tsv{%ends%}
|
* Upload auf den Webserver: {%s%}vgl. Lösung in Kapitel 6.3, Aufgabe 1.{%ends%}
|
||||||
* Erste Zeile der TSV-Dateien anzeigen (sollte die Spaltenüberschriften beinhalten): {%s%}head -n1 *.tsv{%ends%}
|
* Zählung der Zeilen der TSV-Dateien (sollte der Anzahl der Records plus 1 entsprechen): {%s%}wc -l ~/tsv/haw-prozessiert.tsv{%ends%}
|
||||||
|
* Erste Zeile der TSV-Dateien anzeigen (sollte die Spaltenüberschriften beinhalten): {%s%}head -n1 ~/tsv/haw-prozessiert.tsv{%ends%}
|
||||||
|
|
||||||
## Literatur
|
## Literatur
|
||||||
|
|
||||||
* [Exporter in der OpenRefine Dokumentation](https://github.com/OpenRefine/OpenRefine/wiki/Exporters)
|
* [Exporter in der OpenRefine Dokumentation](https://github.com/OpenRefine/OpenRefine/wiki/Exporters)
|
|
@ -13,31 +13,52 @@ Der Client kann ebenso wie OpenRefine lokal installiert werden. Um die Installat
|
||||||
Hinweise:
|
Hinweise:
|
||||||
|
|
||||||
* Die Bedienung ist im Abschnitt "**batch processing with python-client**" im [Repository in Docker Hub](https://hub.docker.com/r/felixlohmeier/openrefine/)) beschrieben. Schauen Sie sich die unter der Überschrift "example for customized run command in interactive mode (e.g. for usage in terminals)" gelisteten Docker-Startbefehle an und wandeln Sie diese so ab, dass sie mit den Parametern im [Kapitel 6.3](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/06_3_openrefine_starten_und_daten_laden.html) beschriebenen Docker-Startbefehl zusammen passen.
|
* Die Bedienung ist im Abschnitt "**batch processing with python-client**" im [Repository in Docker Hub](https://hub.docker.com/r/felixlohmeier/openrefine/)) beschrieben. Schauen Sie sich die unter der Überschrift "example for customized run command in interactive mode (e.g. for usage in terminals)" gelisteten Docker-Startbefehle an und wandeln Sie diese so ab, dass sie mit den Parametern im [Kapitel 6.3](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/06_3_openrefine_starten_und_daten_laden.html) beschriebenen Docker-Startbefehl zusammen passen.
|
||||||
* **Starten Sie Putty zweimal** und bauen Sie jeweils eine SSH-Verbindung auf. Dann können Sie den Server im ersten Putty-Fenster (nennen wir dies im Folgenden Terminal 1) starten und den Client im Zweiten (nennen wir dies im Folgenden Terminal 2).
|
* **Starten Sie zwei SSH-Verbindungen** (Windows: 2x Putty; Mac/Linux: 2x Terminal). Dann können Sie den Server im ersten Fenster (nennen wir dies im Folgenden Terminal 1) starten und den Client im Zweiten (nennen wir dies im Folgenden Terminal 2).
|
||||||
|
|
||||||
## Lösung
|
## Lösung
|
||||||
|
|
||||||
* Terminal 1: Server starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
* Terminal 1: Server starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
||||||
* Terminal 2: Python-Client: {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py{%ends%}
|
* Terminal 2: Python-Client: {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py{%ends%}
|
||||||
|
|
||||||
## Aufgabe 2: Wenden Sie die in Kap. 7.3 gespeicherten Transformationsregeln auf ein neues Projekt an
|
|
||||||
|
## Aufgabe 2: Erstellen Sie ein weiteres Backup und stellen Sie das alte Backup aus Kapitel 7.3 wiederher
|
||||||
|
|
||||||
|
In Kapitel 7.5, Aufgabe 4 haben Sie ein Backup des Arbeitsverzeichnisses von OpenRefine erstellt. Das werden wir jetzt wiederherstellen. Aber vorher erstellen wir noch ein weiteres aktuelles Backup, falls etwas schiefgehen sollte.
|
||||||
|
|
||||||
|
## Vorgehen
|
||||||
|
|
||||||
|
```
|
||||||
|
cd ~
|
||||||
|
cp -r refine refine-backup-fertig-manuell
|
||||||
|
sudo rm -r -f refine
|
||||||
|
cp -r refine-backup refine
|
||||||
|
```
|
||||||
|
|
||||||
|
Damit haben wir den Stand von Kapitel 7.5, Aufgabe 4 wiederhergestellt.
|
||||||
|
|
||||||
|
## Aufgabe 3: Wenden Sie gespeicherte Transformationsregeln auf ein Projekt an
|
||||||
|
|
||||||
Hinweise:
|
Hinweise:
|
||||||
|
|
||||||
* Erstellen Sie ein neues Projekt auf gewohnte Weise (vgl. [Kapitel 6.3](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/06_3_openrefine_starten_und_daten_laden.html), Aufgabe 2)
|
|
||||||
* Nutzen Sie entweder Ihre selbst erstellten Transformationsregeln aus [Kapitel 7.3](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/07_3_fuer_jedes_marc-feld_eine_spalte.html) oder die aus der folgenden Datei: [07_3.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_3.json). Speichern Sie diese Transformationsregeln in einer Datei auf dem Webserver, z.B. **a)** über die Zwischenablage mit ```nano``` (vgl. [Kapitel 3.5](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/03_5_uebung_text_ueber_die_konsole_erstellen.html))
|
* Nutzen Sie entweder Ihre selbst erstellten Transformationsregeln aus [Kapitel 7.3](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/07_3_fuer_jedes_marc-feld_eine_spalte.html) oder die aus der folgenden Datei: [07_3.json](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_3.json). Speichern Sie diese Transformationsregeln in einer Datei auf dem Webserver, z.B. **a)** über die Zwischenablage mit ```nano``` (vgl. [Kapitel 3.5](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/03_5_uebung_text_ueber_die_konsole_erstellen.html))
|
||||||
ODER **b)** laden Sie die Datei mit ```curl``` (vgl. [Kapitel 4.2](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/04_2_uebung_unapi-schnittstelle_des_gbv.html). Die Datei muss im Arbeitsverzeichnis liegen (in unserem Beispiel also in ```/home/stud/refine/```).
|
ODER **b)** laden Sie die Datei mit ```curl``` (vgl. [Kapitel 4.2](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/04_2_uebung_unapi-schnittstelle_des_gbv.html). Die Datei muss im Arbeitsverzeichnis liegen (in unserem Beispiel also in ```/home/stud/refine/```).
|
||||||
|
* Für die Transformationen aus Kapitel 7.3 müssen Sie die Version 2.6rc1 von OpenRefine nutzen (vgl. Kapitel 7.3)
|
||||||
|
|
||||||
## Lösung
|
## Lösung
|
||||||
|
|
||||||
* Terminal 1 - Server starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
* Terminal 1 - Server starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
||||||
* Browser: {%s%}OpenRefine aufrufen und ein neues Projekt erstellen (vgl. Kapitel 6.3, Aufgabe 2){%ends%}
|
|
||||||
* Terminal 2 - Projekte auslesen: {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py{%ends%}
|
* Terminal 2 - Projekte auslesen: {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py{%ends%}
|
||||||
* Terminal 2 - Projekt-ID notieren: {%s%}Notieren Sie die Nummer des gerade erstellten Projekts{%ends%}
|
* Terminal 2 - Projekt-ID notieren: {%s%}Notieren Sie die Nummer eines der vielen Projekte, die noch nicht transformiert wurden, z.B. die ID zu Projektname "haw_2016 10 25_440001 450200 marcxml"{%ends%}
|
||||||
* Terminal 2 - Transformationsdatei erstellen (hier Variante b mit curl): {%s%}curl https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_3.json > /home/stud/refine/07_3.json {%ends%}
|
* Terminal 2 - Transformationsdatei erstellen (hier Variante b mit curl): {%s%}curl https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_3.json > ~/refine/07_3.json{%ends%}
|
||||||
* Terminal 2 - Transformationen anwenden (1234567890123 durch Projekt-ID ersetzen): {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py -f 07_3.json 1234567890123{%ends%}
|
* Terminal 2 - Transformationen anwenden (1234567890123 durch Projekt-ID ersetzen): {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py -f 07_3.json 1234567890123{%ends%}
|
||||||
|
|
||||||
## Aufgabe 3: Exportieren Sie mit dem Python-Client die Daten aus einem Projekt als TSV
|
## Ergebnis
|
||||||
|
|
||||||
|
* Beobachten Sie die Rückmeldungen in den Terminals. Wenn der Prozess fertig ist, erscheint in Terminal 2 (Client) unscheinbar wieder die Eingabezeile. In Terminal 1 (Server) ist die Fertigstellung nicht direkt ersichtlich.
|
||||||
|
* Prüfen Sie nach Fertigstellung das Ergebnis, indem Sie das Projekt im Browser öffnen. Die Daten sollten jetzt transformiert sein und rund 10.000 rows/records anzeigen.
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 4: Exportieren Sie mit dem Python-Client die Daten aus einem Projekt als TSV
|
||||||
|
|
||||||
Hinweise:
|
Hinweise:
|
||||||
|
|
||||||
|
@ -46,17 +67,18 @@ Hinweise:
|
||||||
## Lösung
|
## Lösung
|
||||||
|
|
||||||
* Terminal 1 - Server starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
* Terminal 1 - Server starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
||||||
* Terminal 2 - Daten exportieren (1234567890123 durch Projekt-ID aus Aufgabe 2 ersetzen): {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py 1234567890123 -E --output=test.tsv 1234567890123{%ends%}
|
* Terminal 2 - Daten exportieren (1234567890123 durch Projekt-ID aus Aufgabe 2 ersetzen): {%s%}sudo docker run --link refine-server --rm -v /home/stud/refine:/data felixlohmeier/openrefine:client-py -E --output=test.tsv 1234567890123{%ends%}
|
||||||
* Terminal 2 - Daten anzeigen: {%s%}cat test.tsv | more{%ends%}
|
* Terminal 2 - Daten anzeigen: {%s%}cat ~/refine/test.tsv | more{%ends%}
|
||||||
|
|
||||||
## Aufgabe 4: Schreiben Sie ein Shell-Script, dass Server und Client startet, die Transformation durchführt und dann die Daten als TSV exportiert
|
|
||||||
|
## Aufgabe 5: Schreiben Sie ein Shell-Script, dass Server und Client startet, die Transformation durchführt und dann die Daten als TSV exportiert
|
||||||
|
|
||||||
Hinweise:
|
Hinweise:
|
||||||
|
|
||||||
* Schauen Sie sich die Grundlagen für Shell-Scripte in [Kapitel 4.4](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/04_4_download_der_metadaten.html), Aufgabe 3 nochmal an.
|
* Schauen Sie sich die Grundlagen für Shell-Scripte in [Kapitel 4.4](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/04_4_download_der_metadaten.html), Aufgabe 3 nochmal an.
|
||||||
* Shell-Scripte führen die im Script enthaltenen Befehle Zeile für Zeile einen nach dem anderen aus, sobald der vorige Befehle abgeschlossen ist. Bislang haben wir den OpenRefine-Server im interaktiven Modus gestartet, d.h. der Startbefehl kommt nie von alleine zu Ende und würde die Bearbeitung des restlichen Teils vom Script blockieren. Verwenden Sie daher im Startbefehl des Servers den Parameter ```-d``` anstelle von ```--rm```. Der Server läuft dann endlos im Hintergrund. Sie müssen ihn abschließend manuell beenden mit dem Befehl ```sudo docker stop refine-server``` und löschen mit ```sudo docker rm refine-server```
|
* Shell-Scripte führen die im Script enthaltenen Befehle Zeile für Zeile einen nach dem anderen aus, sobald der vorige Befehle abgeschlossen ist. Bislang haben wir den OpenRefine-Server im interaktiven Modus gestartet, d.h. der Startbefehl kommt nie von alleine zu Ende und würde die Bearbeitung des restlichen Teils vom Script blockieren. Verwenden Sie daher im Startbefehl des Servers den Parameter ```-d``` anstelle von ```--rm```. Der Server läuft dann endlos im Hintergrund. Sie müssen ihn abschließend manuell beenden mit dem Befehl ```sudo docker stop refine-server``` und löschen mit ```sudo docker rm refine-server```
|
||||||
* Der Docker-Container mit dem Server muss vollständig gestartet sein, bevor Sie den Client starten können, denn sonst liefe der ins Leere. Daher sollten Sie eine gewisse Wartezeit einbauen, z.B. mit dem Befehl ```sleep 15```.
|
* Der Docker-Container mit dem Server muss vollständig gestartet sein, bevor Sie den Client starten können, denn sonst liefe dieser ins Leere. Daher sollten Sie eine gewisse Wartezeit einbauen, z.B. mit dem Befehl ```sleep 15```.
|
||||||
* Verwenden Sie ein neues Projekt für Ihre Tests. Wenn Sie Transformationsregeln ein zweites Mal auf ein Projekt anwenden, dann laufen die Transformationen auf den bereits transformierten Daten ab. Das führt mit Sicherheit zu unerwünschten Ergebnissen.
|
* Verwenden Sie stets ein anderes, unbearbeitetes Projekt für Ihre Tests. Wenn Sie Transformationsregeln ein zweites Mal auf ein Projekt anwenden, dann laufen die Transformationen auf den bereits transformierten Daten ab. Das führt mit Sicherheit zu unerwünschten Ergebnissen.
|
||||||
|
|
||||||
## Lösung
|
## Lösung
|
||||||
|
|
||||||
|
@ -105,11 +127,14 @@ exit
|
||||||
**Ausführen:**
|
**Ausführen:**
|
||||||
|
|
||||||
* Diesen Textinhalt in einer Datei abspeichern, z.B. mit ```nano transform+export-minimal.sh```
|
* Diesen Textinhalt in einer Datei abspeichern, z.B. mit ```nano transform+export-minimal.sh```
|
||||||
* IDs der zu verarbeitenden Projekte in der sechsten Zeile des Scripts eingeben: ```nano transform+export-minimal.sh```
|
* IDs der zu verarbeitenden Projekte in der sechsten Zeile des Scripts eingeben. Wählen Sie dazu zwei bislang unbearbeitete Projekte aus. Sie können die Projekt-IDs auch im Browser im Menüpunkt "Open Project" anhand der Links ablesen (project=...)
|
||||||
* Script ausführbar machen: ```chmod +x transform+export-minimal.sh```
|
* Script ausführbar machen: ```chmod +x transform+export-minimal.sh```
|
||||||
* Transformationsdatei 07_3.json in das Arbeitsverzeichnis laden, falls noch nicht vorhanden: ```curl https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_3.json > /home/stud/refine/07_3.json```
|
* Transformationsdatei 07_3.json in das Arbeitsverzeichnis laden, falls noch nicht vorhanden: ```curl https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/07_3.json > ~/refine/07_3.json```
|
||||||
|
* OpenRefine beenden, falls es im anderen Terminal noch laufen sollte.
|
||||||
* Script starten mit ```./transform+export-minimal.sh```
|
* Script starten mit ```./transform+export-minimal.sh```
|
||||||
|
|
||||||
|
Das Script hat eine Laufzeit von etw 5-10 Minuten für 2 Projekte. Währenddessen gibt es keine Rückmeldungen zum Status, also haben Sie etwas Geduld. Wenn das Script fertig gelaufen ist, erscheint wieder die Eingabezeile. Prüfen Sie die beiden transformierten Projekte im Browser. Dazu müssen Sie zunächst wieder OpenRefine manuell starten.
|
||||||
|
|
||||||
### Variante 2: Transformations+Export-Script "Komfort"
|
### Variante 2: Transformations+Export-Script "Komfort"
|
||||||
|
|
||||||
Wie Variante 1 mit folgenden Verbesserungen:
|
Wie Variante 1 mit folgenden Verbesserungen:
|
||||||
|
@ -123,171 +148,49 @@ Wie Variante 1 mit folgenden Verbesserungen:
|
||||||
* Das Script gibt die Konfigurationswerte sowie regelmäßig Start- und Endzeitpunkte aus.
|
* Das Script gibt die Konfigurationswerte sowie regelmäßig Start- und Endzeitpunkte aus.
|
||||||
* Arbeitsverzeichnis, Port und maximaler Arbeitsspeicher für den OpenRefine-Server werden zu Beginn als Variable definiert (Standard: ```/home/stud/refine/```, ```8888```, ```3G```), was eine Anpassung später leichter macht.
|
* Arbeitsverzeichnis, Port und maximaler Arbeitsspeicher für den OpenRefine-Server werden zu Beginn als Variable definiert (Standard: ```/home/stud/refine/```, ```8888```, ```3G```), was eine Anpassung später leichter macht.
|
||||||
|
|
||||||
```
|
**Script als Datei: [transform+export.sh](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/transform+export.sh)**
|
||||||
#!/bin/bash
|
|
||||||
# Script zur Transformation und zum Export von Projekten mit OpenRefine
|
|
||||||
# Variante "Komfort", Stand: 20.11.2016
|
|
||||||
#
|
|
||||||
# Voraussetzungen:
|
|
||||||
# 1. Docker
|
|
||||||
# 2. OpenRefine-Projekte im Arbeitsverzeichnis
|
|
||||||
#
|
|
||||||
# Nutzung Variante A)
|
|
||||||
# IDs der zu verarbeitenden Projekte an den Startbefehl anhängen.
|
|
||||||
# Beispiel: ./transform+export.sh 01234567890123 1234567890123
|
|
||||||
#
|
|
||||||
# Nutzung Variante B)
|
|
||||||
# Codewort TRANSFORM manuell in OpenRefine in den Namen der zu verarbeitenden Projekten aufnehmen
|
|
||||||
# und Script ohne weitere Parameter starten.
|
|
||||||
# Beispiel: ./transform+export.sh
|
|
||||||
#
|
|
||||||
# Transformationen aus den folgenden Dateien werden (in dieser Reihenfolge) durchgeführt
|
|
||||||
# (bei Bedarf direkt hier im Script ändern)
|
|
||||||
jsonfiles=(07_3.json test.json)
|
|
||||||
|
|
||||||
# Weitere Programmvariablen
|
|
||||||
workdir="/home/stud/refine"
|
|
||||||
port=8888
|
|
||||||
ram=3G
|
|
||||||
|
|
||||||
# Variablen ausgeben
|
|
||||||
echo "Transformationsdateien: " ${jsonfiles}
|
|
||||||
echo "Arbeitsverzeichnis: " ${workdir}
|
|
||||||
echo "OpenRefine auf Port: " ${port}
|
|
||||||
echo "OpenRefine max. RAM: " ${ram}
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Startzeitpunkt ausgeben
|
|
||||||
echo "Startzeitpunkt: $(date)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Transformationsdateien ins Arbeitsverzeichnis laden
|
|
||||||
echo "Transformationsdateien herunterladen..."
|
|
||||||
cd ${workdir}
|
|
||||||
for jsonfile in "${jsonfiles[@]}" ; do
|
|
||||||
curl -O https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/openrefine/${jsonfile}
|
|
||||||
done
|
|
||||||
cd - > /dev/null
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Server starten
|
|
||||||
echo "Server starten..."
|
|
||||||
sudo docker run -d --name=refine-server -p ${port}:3333 -v ${workdir}:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m ${ram} -d /data
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Warten bis Server vollständig gestartet ist
|
|
||||||
until curl --silent http://localhost:${port} | cat | grep -q -o "OpenRefine" ; do sleep 3; done
|
|
||||||
|
|
||||||
# Abfrage der Projekt-IDs, wenn mit dem Startbefehl keine benannt wurden
|
|
||||||
if [ -z "$1" ]
|
|
||||||
then
|
|
||||||
echo "Es wurden beim Aufruf des Scripts keine Projekt-IDs benannt."
|
|
||||||
echo ""
|
|
||||||
echo "Projekt-IDs auslesen..."
|
|
||||||
projects=($(sudo docker run --rm --link refine-server -v ${workdir}:/data felixlohmeier/openrefine:client-py | grep "TRANSFORM" | cut -c 2-14))
|
|
||||||
if [ -z "$projects" ]
|
|
||||||
then
|
|
||||||
echo "*** Es konnten keine Projekte gefunden werden! ***"
|
|
||||||
echo ""
|
|
||||||
echo "Sie haben zwei Möglichkeiten Projekte zur Verarbeitung zu benennen:"
|
|
||||||
echo "1. an den Startbefehl des Scripts die IDs der zu verarbeitenden Projekte anhängen"
|
|
||||||
echo "Beispiel: ./transform+export.sh 01234567890123 1234567890123"
|
|
||||||
echo ""
|
|
||||||
echo "2. Das Codewort TRANSFORM manuell in OpenRefine in den Namen der zu verarbeitenden Projekten aufnehmen und das Script erneut starten."
|
|
||||||
echo ""
|
|
||||||
echo "Server beenden und Container löschen..."
|
|
||||||
sudo docker stop refine-server
|
|
||||||
sudo docker rm refine-server
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
echo "Folgende Projekte im Arbeitsverzeichnis tragen das Codewort TRANSFORM im Namen:"
|
|
||||||
echo ${projects[@]}
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Folgende Projekt-IDs wurden beim Aufruf des Script benannt:"
|
|
||||||
projects=($*)
|
|
||||||
echo ${projects[@]}
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Server beenden und Container löschen
|
|
||||||
echo "Server beenden und Container löschen..."
|
|
||||||
sudo docker stop refine-server
|
|
||||||
sudo docker rm refine-server
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Schleife für Transformation und Export der Projekte
|
|
||||||
for projectid in "${projects[@]}" ; do
|
|
||||||
|
|
||||||
echo "Start Projekt $projectid @ $(date)"
|
|
||||||
|
|
||||||
# Server starten
|
|
||||||
echo "Server starten..."
|
|
||||||
sudo docker run -d --name=refine-server -p ${port}:3333 -v ${workdir}:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m ${ram} -d /data
|
|
||||||
|
|
||||||
# Warten bis Server vollständig gestartet ist
|
|
||||||
until curl --silent http://localhost:${port} | cat | grep -q -o "OpenRefine" ; do sleep 3; done
|
|
||||||
|
|
||||||
# Transformationen durchführen
|
|
||||||
for jsonfile in "${jsonfiles[@]}" ; do
|
|
||||||
echo "Transformiere mit ${jsonfile}..."
|
|
||||||
sudo docker run --rm --link refine-server -v ${workdir}:/data felixlohmeier/openrefine:client-py -f ${jsonfile} ${projectid}
|
|
||||||
done
|
|
||||||
|
|
||||||
# Daten exportieren
|
|
||||||
echo "Exportiere in ${projectid}.tsv"
|
|
||||||
sudo docker run --rm --link refine-server -v ${workdir}:/data felixlohmeier/openrefine:client-py -E --output=${projectid}.tsv ${projectid}
|
|
||||||
|
|
||||||
# Server beenden und Container löschen
|
|
||||||
echo "Server beenden und Container löschen..."
|
|
||||||
sudo docker stop refine-server
|
|
||||||
sudo docker rm refine-server
|
|
||||||
|
|
||||||
echo "Ende Projekt $projectid @ $(date)"
|
|
||||||
echo ""
|
|
||||||
done
|
|
||||||
|
|
||||||
# Endzeitpunkt ausgeben
|
|
||||||
echo "Endzeitpunkt: $(date)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Liste der exportierten Dateien
|
|
||||||
echo "Folgende Dateien wurden erfolgreich exportiert:"
|
|
||||||
echo "(Anzahl der Zeilen und Dateigröße in Bytes)"
|
|
||||||
wc -l -c ${workdir}/*.tsv
|
|
||||||
|
|
||||||
exit
|
|
||||||
```
|
|
||||||
|
|
||||||
Script als Datei: [transform+export.sh](https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/transform+export.sh)
|
|
||||||
|
|
||||||
**Ausführen:**
|
**Ausführen:**
|
||||||
|
|
||||||
|
* OpenRefine starten und im Menüpunkt "Open Project" ein bislang unbearbeitetes Projekt umbenennen. Der Link zum Umbenennen erscheint, wenn Sie mit der Maus neben das Änderungsdatum fahren. Schreiben Sie ```TRANSFORM``` vor den Projektnamen.
|
||||||
|
* OpenRefine beenden und Container löschen (falls noch etwas läuft oder der Container aufgrund eines Fehlers nicht richtig gelöscht wurde): ```sudo docker stop refine-server && sudo docker rm refine-server```
|
||||||
* Script mit ```curl``` auf den Server laden: ```curl -O https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/transform+export.sh```
|
* Script mit ```curl``` auf den Server laden: ```curl -O https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/transform+export.sh```
|
||||||
* Script ausführbar machen: ```chmod +x transform+export.sh```
|
* Script ausführbar machen: ```chmod +x transform+export.sh```
|
||||||
* Script starten mit ```./transform+export.sh```
|
* Script starten mit ```./transform+export.sh```
|
||||||
|
|
||||||
## Aufgabe 5: Führen Sie mit dem Script ALLE Transformationsschritte aus Kapitel 7 durch
|
Das Script gibt jetzt auch Rückmeldungen zum aktuellen Status, manche Meldungen sind aber vielleicht irritierend:
|
||||||
|
|
||||||
|
* Die Meldung "(23) Failed writing body" können Sie ignorieren, falls diese erscheinen sollte, das macht nichts ;-).
|
||||||
|
* Die Verarbeitung der Datei test.json wirft einen Fehler, weil dies nur ein Platzhalter ist und dort nichts sinnvolles drinsteht.
|
||||||
|
* Am Ende werden schließlich alle TSV-Dateien gelistet, die im Arbeitsverzeichnis liegen. Daher tauchen auch die TSV-Dateien aus der vorigen Aufgabe mit auf.
|
||||||
|
|
||||||
|
Prüfen Sie die transformierten Projekte im Browser. Dazu müssen Sie zunächst wieder OpenRefine manuell starten.
|
||||||
|
|
||||||
|
|
||||||
|
## Aufgabe 6: Führen Sie mit dem Script ALLE Transformationsschritte aus Kapitel 7 durch
|
||||||
|
|
||||||
Hinweise:
|
Hinweise:
|
||||||
|
|
||||||
* Passen Sie die Zeile ```jsonfiles=(07_3.json test.json)``` so an, dass die gewünschten Transformationsdateien in der richtigen Reihenfolge abgearbeitet werden.
|
* Stellen Sie das Backup aus Kapitel 7.5 wieder her, um einen sauberen Ausgangszustand zu erreichen. Löschen Sie im Browser Testprojekte aus früheren Aufgaben, so dass nur die 45 Projekte mit 10000er Schnipseln verbleiben.
|
||||||
* Als Ausgangsbasis benötigen Sie das Ergebnis von Kapitel 7.5, Aufgabe 3. Wenn Sie damals das Backup, wie vorgeschlagen, erstellt haben, können Sie dies nun wiederherstellen.
|
* Da das Script bzw. der Python-Client keine Projekte erstellen kann, müssen Sie Kapitel 7.5, Aufgabe 7 manuell durchführen. Sie können das Script für die Teil davor und danach einsetzen.
|
||||||
* Da das Script bzw. der Python-Client keine Projekte erstellen kann, müssen Sie Kapitel 7.5, Aufgabe 7 manuell durchführen.
|
* Passen Sie die Zeile ```jsonfiles=(07_3.json test.json)``` im Script jeweils so an, dass alle in Kapitel 7.3-7.7 verwendeten Transformationsdateien in der richtigen Reihenfolge abgearbeitet werden.
|
||||||
|
* Passen Sie die Zeile ```projects=($(sudo docker run --rm --link refine-server -v ${workdir}:/data felixlohmeier/openrefine:client-py | grep "TRANSFORM" | cut -c 2-14))``` im Script so an, dass alle gewünschten Projekte bearbeitet werden.
|
||||||
|
|
||||||
## Lösung
|
## Lösung
|
||||||
|
|
||||||
**Teil 1: mit Script**
|
**Teil 1: mit Script**
|
||||||
|
|
||||||
* Arbeitsverzeichnis löschen (Achtung: Bei Bedarf vorher eine Kopie anlegen!): {%s%}sudo rm -r -f refine{%ends%}
|
* Arbeitsverzeichnis löschen: {%s%}sudo rm -r -f refine{%ends%}
|
||||||
* Backup aus Kapitel 7.5, Aufgabe 3 wiederherstellen: {%s%}cp -r refine-backup_07_5-3 refine{%ends%}
|
* Backup aus Kapitel 7.5, Aufgabe 3 wiederherstellen: {%s%}cp -r refine-backup refine{%ends%}
|
||||||
|
* OpenRefine starten: {%s%}sudo docker run --name=refine-server --rm -p 8888:3333 -v /home/stud/refine:/data felixlohmeier/openrefine:2.6rc1 -i 0.0.0.0 -m 3G -d /data{%ends%}
|
||||||
|
* OpenRefine im Browser aufrufen und Projekte lösen: {%s%}Menü "Open Project" öffnen und Projekte löschen, so dass nur die 45 Projekte mit 10000er Schnipseln verbleiben{%ends%}
|
||||||
|
* OpenRefine beenden
|
||||||
* Script mit ```curl``` auf den Server laden: {%s%}curl -O https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/transform+export.sh{%ends%}
|
* Script mit ```curl``` auf den Server laden: {%s%}curl -O https://felixlohmeier.gitbooks.io/seminar-wir-bauen-uns-einen-bibliothekskatalog/content/scripte/transform+export.sh{%ends%}
|
||||||
* Script ausführbar machen: {%s%}chmod +x transform+export.sh{%ends%}
|
* Script ausführbar machen: {%s%}chmod +x transform+export.sh{%ends%}
|
||||||
* Projekte umbenennen: {%s%}Codewort TRANSFORM in alle Projektnamen schreiben{%ends%}
|
* Script anpassen #1: {%s%}nano transform+export.sh und die Zeile projects=($(sudo docker run --rm --link refine-server -v ${workdir}:/data felixlohmeier/openrefine:client-py | grep "TRANSFORM" | cut -c 2-14)) durch projects=($(sudo docker run --rm --link refine-server -v ${workdir}:/data felixlohmeier/openrefine:client-py | grep "haw" | cut -c 2-14)) ersetzen.{%ends%}
|
||||||
* Script anpassen: {%s%}nano transform+export.sh und die Zeile jsonfiles=(07_3.json test.json) durch jsonfiles=(07_3.json 07_5-6_minimal.json) ersetzen.{%ends%}
|
* Script anpassen #2: {%s%}nano transform+export.sh und die Zeile jsonfiles=(07_3.json test.json) durch jsonfiles=(07_3.json 07_5_minimal.json) ersetzen.{%ends%}
|
||||||
* Script ausführen (Achtung: Mehrere Stunden Laufzeit!): {%s%}./transform+export.sh{%ends%}
|
* Script ausführen (Achtung: Mehrere Stunden Laufzeit!): {%s%}./transform+export.sh{%ends%}
|
||||||
* TSV-Dateien mit WinSCP herunterladen: {%s%}vgl. Lösung in Kapitel 6.3, Aufgabe 1{%ends%}
|
* TSV-Dateien herunterladen: {%s%}vgl. Lösung in Kapitel 6.3, Aufgabe 1{%ends%}
|
||||||
* Arbeitsverzeichnis leeren: {%s%}sudo rm -r -f refine/*{%ends%}
|
* Arbeitsverzeichnis leeren: {%s%}sudo rm -r -f refine/*{%ends%}
|
||||||
|
|
||||||
**Teil 2: manuell**
|
**Teil 2: manuell**
|
||||||
|
@ -299,12 +202,20 @@ Projekt anlegen:
|
||||||
* {%s%}Create Project / Durchsuchen... / Alle TSV Dateien auswählen / Next / Configure Parsing Options{%ends%}
|
* {%s%}Create Project / Durchsuchen... / Alle TSV Dateien auswählen / Next / Configure Parsing Options{%ends%}
|
||||||
* {%s%}Parse data as CSV / TSV / separator-based files{%ends%}
|
* {%s%}Parse data as CSV / TSV / separator-based files{%ends%}
|
||||||
* {%s%}Character encoding: UTF-8{%ends%}
|
* {%s%}Character encoding: UTF-8{%ends%}
|
||||||
* {%s%}Checkbox "Store file source..." deaktivieren / Projektnamen inkl. Codewort TRANSFORM vergeben und Button "Create Project" drücken{%ends%}
|
* {%s%}Checkbox "Store file source..." deaktivieren / Projektnamen "haw-prozessiert-script" vergeben und Button "Create Project" drücken{%ends%}
|
||||||
|
|
||||||
**Teil 3: mit Script**
|
**Teil 3: mit Script**
|
||||||
* Script anpassen: {%s%}nano transform+export.sh und die Zeile jsonfiles=(07_3.json test.json) durch jsonfiles=(07_6-2.json 07_6-3.json) ersetzen.{%ends%}
|
* Script anpassen: {%s%}nano transform+export.sh und die Zeile jsonfiles=(07_3.json test.json) durch jsonfiles=(07_6-2.json 07_6-4.json 07_6-5.json 07_6-6.json 07_6-7.json 07_6-8.json) ersetzen.{%ends%}
|
||||||
* Script ausführen: {%s%}./transform+export.sh{%ends%}
|
* Script ausführen: {%s%}./transform+export.sh{%ends%}
|
||||||
|
|
||||||
|
## Ergebnis
|
||||||
|
|
||||||
|
Die Datei haw-prozessiert-script.tsv im Ordner ~/refine/ ist das Endergebnis der Verarbeitung. Sie können diese Datei mit der vorher manuell erstellten Datei haw-prozessiert.tsv im Ordner ~/tsv/ vergleichen. Im Idealfall sollte das folgende Kommando keine Differenz zwischen den beiden Dateien feststellen können:
|
||||||
|
|
||||||
|
```
|
||||||
|
diff ~/refine/haw-prozessiert-script.tsv ~/tsv/haw-prozessiert.tsv
|
||||||
|
```
|
||||||
|
|
||||||
## Literatur
|
## Literatur
|
||||||
|
|
||||||
* In der Rubrik [häufig gestellte Fragen (FAQ)]((https://github.com/OpenRefine/OpenRefine/wiki/FAQ)) der OpenRefine Dokumentation stehen auch ein paar Tipps, wie OpenRefine programmatisch als Server genutzt werden kann.
|
* In der Rubrik [häufig gestellte Fragen (FAQ)]((https://github.com/OpenRefine/OpenRefine/wiki/FAQ)) der OpenRefine Dokumentation stehen auch ein paar Tipps, wie OpenRefine programmatisch als Server genutzt werden kann.
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"op": "core/column-addition",
|
"op": "core/column-addition",
|
||||||
"description": "Create column Titel at index 48 based on column 245 : a using expression grel:value + if(isNonBlank(cells[\"245 : b\"].value),\". \",\"\") + if(isNonBlank(cells[\"245 : b\"].value),cells[\"245 : b\"].value,\"\") + if(isNonBlank(cells[\"245 : n\"].value),\" - \",\"\") + if(isNonBlank(cells[\"245 : n\"].value),cells[\"245 : n\"].value,\"\") + if(isNonBlank(cells[\"245 : p\"].value),\" - \",\"\") + if(isNonBlank(cells[\"245 : p\"].value),cells[\"245 : p\"].value,\"\") + if(isNonBlank(cells[\"246 : a\"].value),\" - \",\"\") + if(isNonBlank(cells[\"246 : a\"].value),cells[\"246 : a\"].value,\"\")",
|
"description": "Create column Titel at index 48 based on column 245 : a using expression grel:value + if(isNonBlank(cells[\"245 : b\"].value),\". \",\"\") + if(isNonBlank(cells[\"245 : b\"].value),cells[\"245 : b\"].value,\"\") + if(isNonBlank(cells[\"245 : n\"].value),\" - \",\"\") + if(isNonBlank(cells[\"245 : n\"].value),cells[\"245 : n\"].value,\"\") + if(isNonBlank(cells[\"245 : p\"].value),\" - \",\"\") + if(isNonBlank(cells[\"245 : p\"].value),cells[\"245 : p\"].value,\"\") + if(isNonBlank(cells[\"246 : a\"].value),\" - \",\"\") + if(isNonBlank(cells[\"246 : a\"].value),cells[\"246 : a\"].value,\"\")",
|
||||||
"engineConfig": {
|
"engineConfig": {
|
||||||
"facets": [],
|
"mode": "row-based",
|
||||||
"mode": "row-based"
|
"facets": []
|
||||||
},
|
},
|
||||||
"newColumnName": "Titel",
|
"newColumnName": "Titel",
|
||||||
"columnInsertIndex": 48,
|
"columnInsertIndex": 48,
|
||||||
|
|
|
@ -3,17 +3,12 @@
|
||||||
"op": "core/row-removal",
|
"op": "core/row-removal",
|
||||||
"description": "Remove rows",
|
"description": "Remove rows",
|
||||||
"engineConfig": {
|
"engineConfig": {
|
||||||
|
"mode": "row-based",
|
||||||
"facets": [
|
"facets": [
|
||||||
{
|
{
|
||||||
"invert": false,
|
|
||||||
"expression": "isBlank(value)",
|
|
||||||
"selectError": false,
|
|
||||||
"omitError": false,
|
"omitError": false,
|
||||||
|
"expression": "isBlank(value)",
|
||||||
"selectBlank": false,
|
"selectBlank": false,
|
||||||
"name": "Titel",
|
|
||||||
"omitBlank": false,
|
|
||||||
"columnName": "Titel",
|
|
||||||
"type": "list",
|
|
||||||
"selection": [
|
"selection": [
|
||||||
{
|
{
|
||||||
"v": {
|
"v": {
|
||||||
|
@ -21,10 +16,15 @@
|
||||||
"l": "true"
|
"l": "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"selectError": false,
|
||||||
|
"invert": false,
|
||||||
|
"name": "Titel",
|
||||||
|
"omitBlank": false,
|
||||||
|
"type": "list",
|
||||||
|
"columnName": "Titel"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"mode": "row-based"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
"op": "core/multivalued-cell-split",
|
||||||
|
"description": "Split multi-valued cells in column 020 : a",
|
||||||
|
"columnName": "020 : a",
|
||||||
|
"keyColumnName": "001",
|
||||||
|
"separator": "␟",
|
||||||
|
"mode": "plain"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"op": "core/column-addition",
|
"op": "core/column-addition",
|
||||||
"description": "Create column ISBN at index 3 based on column 020 : a using expression grel:value",
|
"description": "Create column ISBN at index 2 based on column 020 : a using expression grel:value",
|
||||||
"engineConfig": {
|
"engineConfig": {
|
||||||
|
"mode": "row-based",
|
||||||
"facets": [
|
"facets": [
|
||||||
{
|
{
|
||||||
"invert": false,
|
|
||||||
"expression": "grel:value.length()",
|
|
||||||
"selectError": false,
|
|
||||||
"omitError": false,
|
"omitError": false,
|
||||||
|
"expression": "grel:value.length()",
|
||||||
"selectBlank": false,
|
"selectBlank": false,
|
||||||
"name": "020 : a",
|
|
||||||
"omitBlank": false,
|
|
||||||
"columnName": "020 : a",
|
|
||||||
"type": "list",
|
|
||||||
"selection": [
|
"selection": [
|
||||||
{
|
{
|
||||||
"v": {
|
"v": {
|
||||||
|
@ -21,48 +24,67 @@
|
||||||
"l": "13"
|
"l": "13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"selectError": false,
|
||||||
|
"invert": false,
|
||||||
|
"name": "020 : a",
|
||||||
|
"omitBlank": false,
|
||||||
|
"type": "list",
|
||||||
|
"columnName": "020 : a"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"mode": "row-based"
|
|
||||||
},
|
},
|
||||||
"newColumnName": "ISBN",
|
"newColumnName": "ISBN",
|
||||||
"columnInsertIndex": 3,
|
"columnInsertIndex": 2,
|
||||||
"baseColumnName": "020 : a",
|
"baseColumnName": "020 : a",
|
||||||
"expression": "grel:value",
|
"expression": "grel:value",
|
||||||
"onError": "set-to-blank"
|
"onError": "set-to-blank"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"op": "core/text-transform",
|
"op": "core/text-transform",
|
||||||
"description": "Text transform on cells in column ISBN using expression grel:'978'+cells[\"020 : a\"].value[0,9]",
|
"description": "Text transform on cells in column ISBN using expression grel:with('978'+cells[\"020 : a\"].value[0,9],v,v+((10-(sum(forRange(0,12,1,i,toNumber(v[i])*(1+(i%2*2)) )) %10)) %10).toString()[0] )",
|
||||||
"engineConfig": {
|
"engineConfig": {
|
||||||
|
"mode": "row-based",
|
||||||
"facets": [
|
"facets": [
|
||||||
{
|
{
|
||||||
"invert": true,
|
|
||||||
"expression": "grel:value.length()",
|
|
||||||
"selectError": false,
|
|
||||||
"omitError": false,
|
"omitError": false,
|
||||||
|
"expression": "grel:value.length()",
|
||||||
"selectBlank": false,
|
"selectBlank": false,
|
||||||
"name": "020 : a",
|
|
||||||
"omitBlank": false,
|
|
||||||
"columnName": "020 : a",
|
|
||||||
"type": "list",
|
|
||||||
"selection": [
|
"selection": [
|
||||||
{
|
{
|
||||||
"v": {
|
"v": {
|
||||||
"v": 13,
|
"v": 10,
|
||||||
"l": "13"
|
"l": "10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"selectError": false,
|
||||||
|
"invert": false,
|
||||||
|
"name": "020 : a",
|
||||||
|
"omitBlank": false,
|
||||||
|
"type": "list",
|
||||||
|
"columnName": "020 : a"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"mode": "row-based"
|
|
||||||
},
|
},
|
||||||
"columnName": "ISBN",
|
"columnName": "ISBN",
|
||||||
"expression": "grel:'978'+cells[\"020 : a\"].value[0,9]",
|
"expression": "grel:with('978'+cells[\"020 : a\"].value[0,9],v,v+((10-(sum(forRange(0,12,1,i,toNumber(v[i])*(1+(i%2*2)) )) %10)) %10).toString()[0] )",
|
||||||
"onError": "keep-original",
|
"onError": "keep-original",
|
||||||
"repeat": false,
|
"repeat": false,
|
||||||
"repeatCount": 10
|
"repeatCount": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "core/multivalued-cell-join",
|
||||||
|
"description": "Join multi-valued cells in column ISBN",
|
||||||
|
"columnName": "ISBN",
|
||||||
|
"keyColumnName": "001",
|
||||||
|
"separator": "␟"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "core/multivalued-cell-join",
|
||||||
|
"description": "Join multi-valued cells in column 020 : a",
|
||||||
|
"columnName": "020 : a",
|
||||||
|
"keyColumnName": "001",
|
||||||
|
"separator": "␟"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
"op": "core/column-addition",
|
"op": "core/column-addition",
|
||||||
"description": "Create column id at index 1 based on column 001 using expression grel:value",
|
"description": "Create column id at index 1 based on column 001 using expression grel:value",
|
||||||
"engineConfig": {
|
"engineConfig": {
|
||||||
"facets": [],
|
"mode": "row-based",
|
||||||
"mode": "row-based"
|
"facets": []
|
||||||
},
|
},
|
||||||
"newColumnName": "id",
|
"newColumnName": "id",
|
||||||
"columnInsertIndex": 1,
|
"columnInsertIndex": 1,
|
||||||
|
|
Loading…
Reference in New Issue