Nachträge Kapitel 4

This commit is contained in:
Felix Lohmeier 2018-01-28 19:19:35 +01:00
parent ccdecd2149
commit 580fab9170
7 changed files with 76127 additions and 34 deletions

View File

@ -2,7 +2,9 @@
## Installation
* Geben Sie im Terminal folgende Befehle ein:
Wir verwenden die Version 7.1 von Solr.
* Geben Sie im Terminal folgende Befehle ein, um diese Version herunterzuladen und zu entpacken:
```
wget http://archive.apache.org/dist/lucene/solr/7.1.0/solr-7.1.0.tgz

View File

@ -19,13 +19,15 @@ Erstellen Sie jetzt einen eigenen Suchindex mit dem Namen `htw`:
## Daten aus Kap. 3.5 laden \(im Terminal\)
Der folgende Befehl indexiert die Daten aus der Datei `einstein.tsv` aus dem Ordner `Downloads` \(ganz am Ende mit der öffnenden spitzen Klammer als input benannt\) im Suchindex `htw`.
Wir benötigen jetzt die in Kapitel 3.5 erstellten Testdaten. Falls Sie dort auf Probleme gestoßen sind, finden Sie auf der Seite [Lösungen](/losungen.md) eine Datei, die Sie hier nutzen können.
Der folgende Befehl indexiert die Daten aus der Datei `einstein.tsv` aus dem Ordner `Downloads` \(die Datei wird ganz am Ende mit der öffnenden spitzen Klammer als input benannt\) im Suchindex `htw`.
```
curl "http://localhost:8983/solr/htw/update/csv?commit=true&separator=%09&split=true&f.creator.separator=%E2%90%9F" --data-binary @- -H 'Content-type:text/plain; charset=utf-8' < ~/Downloads/einstein.tsv
```
Erläuterungen des Befehls:
Weitere Erläuterungen des Befehls:
* Die Basis der URL, die mit curl aufgerufen wird \(`http://localhost:8983/solr/htw/update/csv`\) ist die Adresse des CSV-Update-Handlers von Solr für den Index `htw`.
* Der Teil `commit=true` sorgt dafür, dass die Daten sofort in der Anzeige sichtbar werden.
@ -39,31 +41,32 @@ Weitere mehrfachbelegte Felder ergänzen Sie, indem Sie vor dem zweiten Anführu
&f.title.separator=%E2%90%9F
```
Der komplette Befehl sieht dann wie folgt aus:
```
curl "http://localhost:8983/solr/htw/update/csv?commit=true&separator=%09&split=true&f.contributor.separator=%E2%90%9F&f.coverage.separator=%E2%90%9F&f.creator.separator=%E2%90%9F&f.date.separator=%E2%90%9F&f.description.separator=%E2%90%9F&f.extent.separator=%E2%90%9F&f.format.separator=%E2%90%9F&f.identifier.separator=%E2%90%9F&f.language.separator=%E2%90%9F&f.pages.separator=%E2%90%9F&f.publisher.separator=%E2%90%9F&f.title.separator=%E2%90%9F&f.type.separator=%E2%90%9F" --data-binary @- -H 'Content-type:text/plain; charset=utf-8' < ~/Downloads/einstein.tsv
```
## Prüfen Sie das Ergebnis
Gegebenenfalls erhalten Sie bereits auf den `curl`-Befehl eine Fehlermeldung, dass Daten nicht zum Schema passen. Solr versucht in der Standardeinstellung die Datentypen \(Text, Zahl, Datum, usw.\) automatisch zu erkennen und generiert daraus automatisch ein Schema. Wenn später in der Datei noch andere Daten folgen, die nicht zum "erratenen" Schema passen, dann bricht der Import ab. Dieses Problem behandeln wir im folgenden Kapitel.
In der Browsing-Oberfläche \([http://localhost:8983/solr/htw/browse](http://localhost:8983/solr/htw/browse)\) können Sie prüfen, ob die Daten indexiert wurden. Sie werden feststellen, dass keine Daten im Index angekommen sind.
Fehlermeldungen finden Sie in der Administrationsoberfläche im Bereich "Logging": [http://localhost:8983/solr/\#/~logging](http://localhost:8983/solr/#/~logging)
Schauen Sie noch einmal in das Terminal. Auf den `curl`-Befehl hatten Sie eine Rückmeldung erhalten, aus der das Problem ersichtlich ist. Darin steht unter anderem:
In der Browsing-Oberfläche \([http://localhost:8983/solr/gettingstarted/browse](http://localhost:8983/solr/gettingstarted/browse)\) können Sie genauer prüfen, ob die Daten richtig indexiert wurden.
> Error adding field 'date'='uuuu' msg=For input string: \"uuuu\"
## Falls etwas völlig schiefgeht...
Fehlermeldungen finden Sie übrigens auch in der Administrationsoberfläche im Bereich "Logging": [http://localhost:8983/solr/\#/~logging](http://localhost:8983/solr/#/~logging)
Der folgende Befehl löscht alle Daten im Index `htw`:
Warum ist die Indexierung gescheitert?
```
curl "http://localhost:8983/solr/htw/update?commit=true" -H "Content-Type: text/xml" --data-binary '<delete><query>*:*</query></delete>'
```
* Solr versucht in der Standardeinstellung die Datentypen \(Text, Zahl, Datum, usw.\) automatisch zu erkennen und generiert daraus automatisch ein Schema. Wenn später in der Datei noch andere Daten folgen, die nicht zum "erratenen" Schema passen, dann bricht der Import ab.
* Die ersten Datensätze in unserer TSV-Datei enthalten in der Spalte `date` eine Jahreszahl (1967, 1980, 1979 usw.). Solr schließt daraus, dass das Feld `date` nur Zahlen beinhalten darf und verwendet den Feldtyp `plongs` (TrieLongField, 64-bit signed integer).
* In einem der hinteren Datensätze unserer TSV-Datei stehen in der Spalte `date` Buchstaben (uuuu). Buchstaben sind im Feldtyp `plongs` nicht zugelassen. Daher bricht der Import ab.
Wenn auch andere Einstellungen \(wie z.B. das Schema\) durch fehlerhafte Importe verhunzt sind, dann können Sie im Administrationsbereich "Core Admin" auch den ganzen Suchindex \("Core"\) inklusive aller Einstellungen löschen. Das Löschen wird dort vornehm als "unload" bezeichnet.
Wir müssen also entweder das Schema manuell definieren oder die Daten vereinheitlichen, damit wir diese erfolgreich indexieren können. Darum kümmern wir uns im nächsten Kapitel.
[http://localhost:8983/solr/\#/~cores/htw](http://localhost:8983/solr/#/~cores/htw)
Anschließend können Sie oben beim Abschnitt "Index erstellen" wieder beginnen.
Das `u` steht übrigens für `Date element is totally or partially unknown` und ist im MARC-Feld `008` Zeichen 7-10 [explizit zugelassen](https://www.loc.gov/marc/bibliographic/bd008a.html). Da der Suchindex Apache Solr mit dem `u` aber nichts anfangen kann, hätten wir dies in der Transformation in Kapitel 3.5 berücksichtigen müssen. Eine Lösungsmöglichkeit wäre gewesen, die Ungenauigkeit durch einen Zeitraum (Anfangs- und Enddatum) auszudrücken. Dafür gibt es in Solr [weitreichende Möglichkeiten](https://lucene.apache.org/solr/guide/7_1/working-with-dates.html#WorkingwithDates-DateRangeFormatting).
## Literatur
* [Offizielle Anleitung zum Einspielen von CSV-Daten](https://lucene.apache.org/solr/guide/7_1/uploading-data-with-index-handlers.html#csv-formatted-index-updates)

View File

@ -2,13 +2,20 @@
Ab Solr Version 6.0 ist das sogenannte "managed schema" \(auch "schemaless mode" genannt\) voreingestellt. Solr analysiert bei der Indexierung die Daten und versucht das Schema selbst zu generieren. Felder können aber weiterhin zusätzlich manuell definiert werden.
## Schema über Admin-Oberfläche konfigurieren
Rufen Sie dazu die Admin-Oberfläche auf. Wählen Sie im Menü "Core Selector" den Index "htw" und dann im zweiten Menü den Punkt "Schema". Direktlink: [http://localhost:8983/solr/\#/htw/schema](http://localhost:8983/solr/#/htw/schema)
## Automatisch erkanntes Feld date löschen
Durch die Indexierung in Kapitel 4.3 hat Solr automatisch einige Felder im Schema definiert. Rufen Sie im Menü das Feld `date` auf. Sie werden sehen, dass als Feldtyp `plongs` definiert wurde. Direkte Änderungen sind hier nicht möglich, daher drücken Sie den Button `delete field` und bestätigen Sie die Sicherheitsabfrage mit `delete`.
## Feld date manuell neu anlegen
Nun können wir das Feld `date` manuell definieren. Gehen Sie dazu wie folgt vor:
* Admin-Oberfläche aufrufen. Im Menü "Core Selector" den Index "htw" auswählen. Dann im zweiten Menü "Schema" aufrufen. Direktlink: [http://localhost:8983/solr/\#/htw/schema](http://localhost:8983/solr/#/htw/schema)
* Button "Add Field" drücken
* Name eingeben \(Groß- und Kleinschreibung ist wichtig\)
* `field type` \(z.B. string\) auswählen
* ggf. die Checkbox `multivalued` markieren, wenn das Feld mehrere Werte \(getrennt durch ein Trennzeichen\) enthält
* Name `date` eingeben \(Groß- und Kleinschreibung ist wichtig\)
* Als `field type` die Option `text_general` auswählen (damit ist fast alles erlaubt)
* Button `Add field` drücken
## "Catchall" Copy Field anlegen
@ -34,11 +41,13 @@ Schritt 2: `einstein.tsv` indexieren \(hier mit Mehrfachbelegungen\):
curl "http://localhost:8983/solr/htw/update/csv?commit=true&separator=%09&split=true&f.contributor.separator=%E2%90%9F&f.coverage.separator=%E2%90%9F&f.creator.separator=%E2%90%9F&f.date.separator=%E2%90%9F&f.description.separator=%E2%90%9F&f.extent.separator=%E2%90%9F&f.format.separator=%E2%90%9F&f.identifier.separator=%E2%90%9F&f.language.separator=%E2%90%9F&f.pages.separator=%E2%90%9F&f.publisher.separator=%E2%90%9F&f.title.separator=%E2%90%9F&f.type.separator=%E2%90%9F" --data-binary @- -H 'Content-type:text/plain; charset=utf-8' < ~/Downloads/einstein.tsv
```
## Ergebnis prüfen
Rufen Sie nun erneut die Browsing-Oberfläche \([http://localhost:8983/solr/htw/browse](http://localhost:8983/solr/htw/browse)\) auf. Jetzt sollten die Daten erscheinen und suchbar sein.
## Literatur
* [Exercise 2: Modify the Schema and Index Films Data \(im Solr Tutorial\)](http://lucene.apache.org/solr/guide/7_1/solr-tutorial.html#exercise-2)
* [Einführungsartikel zu "Managed Schema"](https://support.lucidworks.com/hc/en-us/articles/221618187-What-is-Managed-Schema-)
* [Einführungsartikel zur Definition von Feldern im Schema](http://www.solrtutorial.com/schema-xml.html)

View File

@ -8,8 +8,7 @@ In Kapitel 3 haben wir im OpenRefine Tutorial mit Daten des Powerhouse Museum ge
## Aufgabe 1: Transformieren Sie die Daten des Powerhouse Museum mit OpenRefine
* Benennen Sie die Spalten so um, dass Sie auf die Feldbezeichnungen in unserem Schema (Dublin Core) passen.
* Erstellen Sie eine Spalte `id` mit einem eindeutigen Identifier pro Zeile
* Benennen Sie die Spalten so um, dass Sie auf die Feldbezeichnungen in unserem Schema (Dublin Core) passen. Die erste Spalte muss `id` lauten und muss mit einem eindeutigen Identifier versehen sein.
* Exportieren Sie die Daten als TSV
## Aufgabe 2: Indexieren Sie die Daten in Solr

View File

@ -61,13 +61,18 @@ Folgende Regeln stehen \(leicht vereinfacht\) darin:
* dc:identifier aus MARC 856u und 020a
* dc:rights aus MARC 506a, 540a
## [4.3 Daten in Solr laden](//kapitel-4/43-daten-in-solr-laden.md)
## [4.5 Bonus: Weitere Daten indexieren](//kapitel-4/45-weitere-daten-indexieren.md)
Befehl mit Mehrfachbelegungen
### Aufgabe 1
Starten Sie OpenRefine (`~/openrefine-2.7/refine`) und laden Sie das in Kapitel 3.5 bearbeitete Projekt (die Schritte aus dem Tutorial sollten bereits durchgeführt sein).
Wenden Sie die folgende JSON-Datei mit Transformationsregeln für ein Mapping auf Dublin Core an: [openrefine-powerhouse.json](https://raw.githubusercontent.com/felixlohmeier/kurs-bibliotheks-und-archivinformatik/master/openrefine/openrefine-powerhouse.json)
Exportieren Sie die Daten als TSV und speichern Sie die Datei im Ordner `Downloads`. Ergebnis: [openrefine/powerhouse.tsv](https://github.com/felixlohmeier/kurs-bibliotheks-und-archivinformatik/raw/master/openrefine/powerhouse.tsv)
### Aufgabe 2
```
curl "http://localhost:8983/solr/htw/update/csv?commit=true&separator=%09&split=true&f.contributor.separator=%E2%90%9F&f.coverage.separator=%E2%90%9F&f.creator.separator=%E2%90%9F&f.date.separator=%E2%90%9F&f.description.separator=%E2%90%9F&f.extent.separator=%E2%90%9F&f.format.separator=%E2%90%9F&f.identifier.separator=%E2%90%9F&f.language.separator=%E2%90%9F&f.pages.separator=%E2%90%9F&f.publisher.separator=%E2%90%9F&f.title.separator=%E2%90%9F&f.type.separator=%E2%90%9F" --data-binary @- -H 'Content-type:text/plain; charset=utf-8' < ~/Downloads/einstein.tsv
curl "http://localhost:8983/solr/htw/update/csv?commit=true&separator=%09&split=true&f.contributor.separator=%E2%90%9F&f.coverage.separator=%E2%90%9F&f.creator.separator=%E2%90%9F&f.date.separator=%E2%90%9F&f.description.separator=%E2%90%9F&f.extent.separator=%E2%90%9F&f.format.separator=%E2%90%9F&f.identifier.separator=%E2%90%9F&f.language.separator=%E2%90%9F&f.pages.separator=%E2%90%9F&f.publisher.separator=%E2%90%9F&f.title.separator=%E2%90%9F&f.type.separator=%E2%90%9F" --data-binary @- -H 'Content-type:text/plain; charset=utf-8' < ~/Downloads/powerhouse.tsv
```

View File

@ -0,0 +1,347 @@
[
{
"op": "core/column-rename",
"description": "Rename column Record ID to id",
"oldColumnName": "Record ID",
"newColumnName": "id"
},
{
"op": "core/text-transform",
"description": "Text transform on cells in column id using expression grel:\"powerhouse\" + value",
"engineConfig": {
"mode": "row-based",
"facets": []
},
"columnName": "id",
"expression": "grel:\"powerhouse\" + value",
"onError": "keep-original",
"repeat": false,
"repeatCount": 10
},
{
"op": "core/column-rename",
"description": "Rename column Object Title to title",
"oldColumnName": "Object Title",
"newColumnName": "title"
},
{
"op": "core/column-rename",
"description": "Rename column Description. to description",
"oldColumnName": "Description.",
"newColumnName": "description"
},
{
"op": "core/column-rename",
"description": "Rename column Production Date to date",
"oldColumnName": "Production Date",
"newColumnName": "date"
},
{
"op": "core/column-rename",
"description": "Rename column License info to rights",
"oldColumnName": "License info",
"newColumnName": "rights"
},
{
"op": "core/column-rename",
"description": "Rename column Categories to type",
"oldColumnName": "Categories",
"newColumnName": "type"
},
{
"op": "core/text-transform",
"description": "Text transform on cells in column type using expression grel:value.replace('|','␟')",
"engineConfig": {
"mode": "row-based",
"facets": []
},
"columnName": "type",
"expression": "grel:value.replace('|','␟')",
"onError": "keep-original",
"repeat": false,
"repeatCount": 10
},
{
"op": "core/multivalued-cell-split",
"description": "Split multi-valued cells in column Provenance (Production)",
"columnName": "Provenance (Production)",
"keyColumnName": "id",
"separator": "|",
"mode": "plain"
},
{
"op": "core/column-addition",
"description": "Create column tmp_creator at index 7 based on column Provenance (Production) using expression grel:value.match(/([A-Z]\\w+): (.*)/)[1]",
"engineConfig": {
"mode": "row-based",
"facets": []
},
"newColumnName": "tmp_creator",
"columnInsertIndex": 7,
"baseColumnName": "Provenance (Production)",
"expression": "grel:value.match(/([A-Z]\\w+): (.*)/)[1]",
"onError": "set-to-blank"
},
{
"op": "core/column-addition",
"description": "Create column tmp_creator_role at index 7 based on column Provenance (Production) using expression grel:value.match(/([A-Z]\\w+): (.*)/)[0]",
"engineConfig": {
"mode": "row-based",
"facets": []
},
"newColumnName": "tmp_creator_role",
"columnInsertIndex": 7,
"baseColumnName": "Provenance (Production)",
"expression": "grel:value.match(/([A-Z]\\w+): (.*)/)[0]",
"onError": "set-to-blank"
},
{
"op": "core/column-addition",
"description": "Create column creator at index 9 based on column tmp_creator using expression grel:value",
"engineConfig": {
"mode": "record-based",
"facets": [
{
"omitError": false,
"expression": "value",
"selectBlank": false,
"selection": [
{
"v": {
"v": "Artist",
"l": "Artist"
}
},
{
"v": {
"v": "Designer",
"l": "Designer"
}
},
{
"v": {
"v": "Author",
"l": "Author"
}
},
{
"v": {
"v": "Maker",
"l": "Maker"
}
}
],
"selectError": false,
"invert": false,
"name": "tmp_creator_role",
"omitBlank": false,
"type": "list",
"columnName": "tmp_creator_role"
}
]
},
"newColumnName": "creator",
"columnInsertIndex": 9,
"baseColumnName": "tmp_creator",
"expression": "grel:value",
"onError": "set-to-blank"
},
{
"op": "core/column-addition",
"description": "Create column contributor at index 9 based on column tmp_creator using expression grel:value",
"engineConfig": {
"mode": "record-based",
"facets": [
{
"omitError": false,
"expression": "value",
"selectBlank": true,
"selection": [
{
"v": {
"v": "Artist",
"l": "Artist"
}
},
{
"v": {
"v": "Designer",
"l": "Designer"
}
},
{
"v": {
"v": "Author",
"l": "Author"
}
},
{
"v": {
"v": "Maker",
"l": "Maker"
}
}
],
"selectError": false,
"invert": true,
"name": "tmp_creator_role",
"omitBlank": false,
"type": "list",
"columnName": "tmp_creator_role"
}
]
},
"newColumnName": "contributor",
"columnInsertIndex": 9,
"baseColumnName": "tmp_creator",
"expression": "grel:value",
"onError": "set-to-blank"
},
{
"op": "core/text-transform",
"description": "Text transform on cells in column creator using expression grel:value + \" (\" + cells[\"tmp_creator_role\"].value + \")\"",
"engineConfig": {
"mode": "record-based",
"facets": [
{
"omitError": false,
"expression": "isBlank(value)",
"selectBlank": false,
"selection": [
{
"v": {
"v": false,
"l": "false"
}
}
],
"selectError": false,
"invert": false,
"name": "creator",
"omitBlank": false,
"type": "list",
"columnName": "creator"
}
]
},
"columnName": "creator",
"expression": "grel:value + \" (\" + cells[\"tmp_creator_role\"].value + \")\"",
"onError": "keep-original",
"repeat": false,
"repeatCount": 10
},
{
"op": "core/text-transform",
"description": "Text transform on cells in column contributor using expression grel:value + \" (\" + cells[\"tmp_creator_role\"].value + \")\"",
"engineConfig": {
"mode": "record-based",
"facets": [
{
"omitError": false,
"expression": "isBlank(value)",
"selectBlank": false,
"selection": [
{
"v": {
"v": false,
"l": "false"
}
}
],
"selectError": false,
"invert": false,
"name": "contributor",
"omitBlank": false,
"type": "list",
"columnName": "contributor"
}
]
},
"columnName": "contributor",
"expression": "grel:value + \" (\" + cells[\"tmp_creator_role\"].value + \")\"",
"onError": "keep-original",
"repeat": false,
"repeatCount": 10
},
{
"op": "core/column-removal",
"description": "Remove column Provenance (Production)",
"columnName": "Provenance (Production)"
},
{
"op": "core/column-removal",
"description": "Remove column tmp_creator_role",
"columnName": "tmp_creator_role"
},
{
"op": "core/column-removal",
"description": "Remove column tmp_creator",
"columnName": "tmp_creator"
},
{
"op": "core/column-removal",
"description": "Remove column Provenance (History)",
"columnName": "Provenance (History)"
},
{
"op": "core/column-removal",
"description": "Remove column Marks",
"columnName": "Marks"
},
{
"op": "core/column-rename",
"description": "Rename column Registration Number to identifier",
"oldColumnName": "Registration Number",
"newColumnName": "identifier"
},
{
"op": "core/column-removal",
"description": "Remove column Height",
"columnName": "Height"
},
{
"op": "core/column-removal",
"description": "Remove column Width",
"columnName": "Width"
},
{
"op": "core/column-removal",
"description": "Remove column Depth",
"columnName": "Depth"
},
{
"op": "core/column-removal",
"description": "Remove column Diameter",
"columnName": "Diameter"
},
{
"op": "core/column-removal",
"description": "Remove column Weight",
"columnName": "Weight"
},
{
"op": "core/column-removal",
"description": "Remove column identifier",
"columnName": "identifier"
},
{
"op": "core/column-rename",
"description": "Rename column Persistent Link to identifier",
"oldColumnName": "Persistent Link",
"newColumnName": "identifier"
},
{
"op": "core/multivalued-cell-join",
"description": "Join multi-valued cells in column contributor",
"columnName": "contributor",
"keyColumnName": "id",
"separator": "␟"
},
{
"op": "core/multivalued-cell-join",
"description": "Join multi-valued cells in column creator",
"columnName": "creator",
"keyColumnName": "id",
"separator": "␟"
}
]

75728
openrefine/powerhouse.tsv Normal file

File diff suppressed because it is too large Load Diff