2020.06 2021.06

Solr und MyCoRe

Dieses Kapitel beschäftigt sich mit der Einbindung der Apache Solr-Suchmaschine in MyCoRe. Die MyCoRe-Releases 2020.06 LTS und 2021.06 LTS wurden erfolgreich mit Solr 8.9.x getestet.

Solr Konfiguration für MyCoRe

Falls noch kein Solr Server zur Verfügung steht, kann er gemäß der Anleitung im Abschnitt Einrichtung eines Solr-8-Servers installiert werden.

Nun müssen für jede MyCoRe-Anwendung ein oder mehrere Solr-Cores angelegt werden. Da sich noch nicht alle Konfigurationsdateien für einen Core über die die Solr-API erstellen lassen, werden Templates (configuration sets) für die Basiskonfiguration durch MyCoRe über GitHub bereitgestellt.

Da verschiedene MyCoRe Komponenten und Module individuelle Suchfelder und Datentypen benötigen, können diese direkt in den Modulen definiert werden. Mittels eines MyCoRe-Kommandos werden diese Definitonsdateien ausgelesen und über die Solr Schema API in den Core geschrieben.

Begrifflichkeiten im Zusammenhang mit MyCoRe

Im Zusammenhang mit der Nutzung der Kommandos zur Konfiguration von SOLR-Cores in MyCoRe sind einige Begiffe zu definieren. Dies soll Missverständnisse bei der Nutzung vermeiden.

  • Configuration Set - config_set - dies beschreibt ein vorgefertigtes Template, welches alternativ zu dem in SOLR mitgelieferten _default -Template für alle MyCoRe-Anwendungen zum erstellen eines leeren Cores eingesetzt werden kann.
  • Core Configuration Type - core_config_type bezeichnet die Art der Konfiguration. Festgelegt wurden die Arten main und classification . Die Typangabe beschreibt den Pfad zu den JSON-API-Vorlagen in den einzelnen MyCoRe-Modulen (z. B. .../{modulname}/config/solr/{core_config_type}/solr-schema.json )
  • CoreId - core_id ist eine fiktive ID, welch dafür sorgen soll, die einzelnen Cores einer Anwendung zu bezeichnen und ihnen spezifische Konfigurationen zuweisen zu können. Standardmäßig werden diese gleichlautend wie dei dazu passenden Konfigurationstypen mit main und classification bezeichnet.
  • CoreName - core_name ist der konkrete Name des Cores aus Sicht SOLR. Dies ist auch der Name, unter dem der Core tatsächlich in SOLR zu finden ist.

Configuration Sets laden

Die Basis-Konfiguration eines Solr-Cores erfolgt über Configuration Sets. Bei GitHub werden verschiedene MyCoRe-Config-Sets zur Verfügung gestellt. Für den Solr-Core vom Typ main wird das mycore_solr_configset_main benötigt.

Um das Set in den Solr-Server zu integrieren, können folgende Kommandos ausgeführt werden:

1
2
 cd .../solr/server/solr/configsets
 git clone https://github.com/MyCoRe-Org/mycore_solr_configset_main.git mycore_main

Alternativ kann das Verzeichnis auch manuell heruntergeladen und in diesen Ordner kopiert werden. Analog kann dies für das Klassifikations-Set aufgerufen werden:

1
 git clone https://github.com/MyCoRe-Org/mycore_solr_configset_classification.git mycore_classification

Standard Solr Core (main) erzeugen

Basierend auf dem bereitgestellten Configuration Set wird nun ein Solr Core erzeugt. Als Name des main Cores kann der Name der MyCoRe-Anwendung gewählt werden.

1
2
3
 .../solr/bin/solr create -c {core_name} -d {config_set}
 .../solr/bin/solr create -c my_core_name -d mycore_main
        

Falls noch nicht geschehen, sollte jetzt die Solr-Server-URL der MyCoRe-Anwendung über ein Property bekannt gemacht werden (siehe MyCoRe-Konfigurationsverzeichnis ). Weiterhin können für die einzelnen CoreIds der Name und falls abweichend auch die URLs definiert werden. Die CoreId main ist dabei immer erforderlich. Weitere CoreIds wie classification sind optional. Es ist auch möglich, den Core auf einem anderen Solr Server zu erstellen. In diesem Fall muss zusätzlich das Property MCR.Solr.Core.{core_id}.ServerURL gesetzt werden. Somit können Solr-Cores auch auf verschiedenen physischen Hosts liegen.

1
2
3
4
5
          MCR.Solr.ServerURL=http://localhost:8983/
          MCR.Solr.Core.main.Name=my_core_name
          MCR.Solr.Core.main.ServerURL=%MCR.Solr.ServerURL%
          ...
        

Alternativ können die CoreIds (auf jeden Fall die CoreId main ) über die MyCoRe-CLI registriert werden. Diese Einstelllungen sind jedoch nicht persistent.

1
2
3
          mycore.sh register solr core with name {core_name} as core main
          mycore.sh register solr core with name my_core_name as core main
        

Anschließend kann über die SOLR-Web-Oberfläche geprüft werden, ob der Core richtig angelegt wurde (http://localhost:8983/solr/#/~cores).

Über das MyCoRe-Kommando show solr configuration kann eine Liste der zu setzenden Properties in der CLI angezeigt werden.

Solr Konfiguration und Schema erstellen

Die Konfiguration der Solr-Suchfelder, Request-Handler, ... wurden seit MyCoRe 2018.06 LTS auf die Module und Komponenten aufgeteilt, in denen sie verwendet werden. Die Basisfelder / -Konfiguration für alle MyCoRe-Anwendungen befindet sich in der Komponente mycore-solr.

Je nach Anwendungsfall kann es sein, dass neben dem Solr-Core vom Typ main weitere Definitionen für andere Core Typen (z. B. classification) erstellt werden müssen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 {mycore-module}/src/main/resources/components/{module_name}/config/solr
   or
 {application-module}/src/main/resources/config/{application-module}/solr

 .../main - the core that use each MyCoRe application
    .../solr-schema.json - vorhanden, wenn das Modul das Solr-Schema erweitert
    .../solr-config.json - vorhanden, wenn das Modul die Solr-Konfiguration erweitert

 .../{other_type} - other core definitions
    .../solr-schema.json - vorhanden, wenn das Modul das Solr-Schema erweitert
    .../solr-config.json - vorhanden, wenn das Modul die Solr-Konfiguration erweitert

Die JSON-Dateien bestehen aus Json-Arrays, die Kommandos der Solr-Schema bzw. Solr-Configuration API enthalten. Sollen bereits bestehende / in MyCoRe vorhandene Felder oder ihre Definition geändert werden, kann dies über replace-Anweisungen in den JSON-Konfigurationsdateien erfolgen.

In Solr wird die anwenderseitige Konfiguration in der gesonderten Datei configoverlay.json im jeweiligen Kern abgelegt. Hier können Einträge aus den Gruppen stehen, welche im Property MCR.Solr.ObserverConfigTypes definiert sind. Ggf. sind in diesen Definitionen auch Verweise auf eigene SOLR-FieldTypes vorhanden. Diese Elemente (z. B. ein RequestHandler) müssen beim Reload der SOLR-Kern-Konfiguration vorher gelöscht werden. Um nicht all Konfigurationen wahllos zu löschen, sind diese im mycore.properties des jeweiligen Datenmodells explizit zum Löschen anzugeben.

1
 MCR.Solr.ObserverConfigTypes.{observedType}.toClean={my_request_handler},...

Über ein MyCoRe-CLI Kommando wird die Konfiguration geladen. Im Normalfall lautet das Kommando:

1
2
 mycore.sh reload solr configuration {core_config_type} in core {core_id}
 mycore.sh reload solr configuration main in core main

Anschließend sollte noch einmal über die Solr-Web-Oberfläche geprüft werden, ob der Core vollständig konfiguriert wurde. Weiterhin sollte im MyCoRe-Log / in der Kommandozeile geprüft werden, ob Solr sämtliche Konfigurationskommandos ausgeführt hat. Ist alles okay, so ist der Core betriebsbereit.

(siehe Solr Control Script Reference, Schema API und Config API)

Das Solr-Document

Die in Solr zu speichernden Daten werden als Solr-Document über eine Kette von XSLT-Transformationen generiert. Hierfür ist das Property MCR.URIResolver.xslImports.solr-document zuständig. Grundsätzlich in der Kette enthalten sind die Stylesheets solr-basetemplate.xsl und mycoreobject-dynamicfields.xsl. Weitere Transformer können dieser Kette angefügt werden (siehe Beispielcode). Der an Solr ausgehende Datenstrom läßt sich im Web-Browser mit der URL http://{myapp}/receive/{mycore_id}?XSL.Style=solrdocument überprüfen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:mcrxsl="xalan://org.mycore.common.xml.MCRXMLFunctions"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns:xalan="http://xml.apache.org/xalan"
  exclude-result-prefixes="xalan xlink mcrxsl">
   
  <xsl:import href="xslImport:solr-document:viaf2solr.xsl" />
  
  <xsl:template match="mycoreobject[contains(@ID,'_{my_datamodel}_')]">
    <xsl:apply-imports />
    <!-- field name="viaf_name_all" type="text_general" multiValued="true" stored="true" -->
    <xsl:for-each select="./metadata/def.preferredName/preferredName">
      <field name="viaf_name_all">
        <xsl:value-of select="fullname/text()" />
      </field>
    </xsl:for-each>
    ...
  </template>
</stylesheet>

Über verschiedene rebuild Kommandos (siehe Kommandos zur Arbeit mit Solr) können die Daten in den Solr Core eingespielt werden. Um alle Daten zu indexieren, kann folgendes Kommando verwendet werden:

1
 rebuild solr metadata and content index in core main

Eigene Request-Handler einbinden

MyCoRe verhindert grundsätzlich den Gebrauch eigener Request-Handler solange diese nicht MyCoRe bekannt sind. Grundsätzlich sind nur die Handler /select und /update aus Sicherheitsgründen zugelassen. Sollen weitere Handler benutzt werden, so müssen diese im Property MCR.Solr.Proxy.WhiteList hinzugefügt werden. Dies kann mit folgender Konfiguration erfolgen:

1
 MCR.Solr.Proxy.WhiteList=%MCR.Solr.Proxy.WhiteList%,/myhandler

Solr und Content Security Policy

Mit Solr8 kommt bei den Responses die Content Security Policy (CSP) im Header zum tragen. Diese Policies werden in MyCoRe an die Layout-Komponenten weiter gegeben. Nutzt die Webseite externe Referenzen, kann das zu Konflikten führen. Um die CSP zu überschreiben, wurde das folgende Property eingeführt. Diese kann die CSP aus Solr ersetzen oder, wenn es leer ist, diese abschalten.

1
  MCR.Solr.HTTPResponseHeader.Content-Security-Policy=default-src 'none'; base-uri 'none'; connect-src 'self'; form-action 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://...; worker-src 'self';

Properties für die Solr-Komponente

Property Bedeutung in App.-Config
MCR.Solr.ServerURL default URL für den Solr-Server, z.B. http://mysolr.de:8983/ (ohne /solr am Ende) required
MCR.Solr.Core.{core_id}.Name Name des Solr Cores (wird Pfadbestandteil der Solr-URL zum Core) required
MCR.Solr.Core.{core_id}.ServerURL Basis-URL des Solr-Servers, falls der Core nicht auf dem Standard-Server (s.o.) installiert wurde
MCR.Solr.Indexer.File.AccumulatorList ???
MCR.Solr.Indexer.BulkSize default=100 ; Die Anzahl der Objekte, die mit einem Mal an Solr geschickt werden.
MCR.Solr.Indexer.ThreadCount default=4 ; Anzahl der benutzten Threads
MCR.Solr.XMLProtocolVersion current=4.5
MCR.Solr.SelectProxy.MaxConnections default=20 ; max. Anzahl der Verbindungen zum Solr-Server für select
MCR.Solr.SelectPath default=/select
MCR.Solr.UpdatePath default=/update
MCR.Solr.ExtractPath default=/update/extract
MCR.Solr.Proxy.WhiteList default=/select ; der Proxy akzeptiert nur die Liste davon
MCR.Solr.SolrClient.ConnectionTimeout default=0
MCR.Solr.SolrClient.SocketTimeout default=50000
MCR.Solr.ConcurrentUpdateSolrClient.Enabled default=true ; soll das Update parallel erfolgen?
MCR.Solr.ConcurrentUpdateSolrClient.QueueSize default=100
MCR.Solr.ConcurrentUpdateSolrClient.ThreadCount Wert entspricht dem Property MCR.Solr.Indexer.ThreadCount
MCR.Solr.SolrInputDocument.Factory default=org.mycore.solr.index.document.MCRSolrTransformerInputDocumentFactory
MCR.Solr.SolrInputDocument.Transformer default=mycoreobject-solrdocument
MCR.Solr.SolrInputDocument.Path.Factory default=org.mycore.solr.index.file.MCRSolrPathDocumentFactory
MCR.Solr.IndexHandler.Factory default=org.mycore.solr.index.handlers.MCRSolrLazyInputDocumentHandlerFactory
MCR.Solr.FileIndexStrategy default=org.mycore.solr.index.strategy.MCRSolrMimeTypeStrategie
MCR.Solr.MimeTypeStrategy.Pattern default=image/.*
MCR.Solr.DynamicFields default=true ; erzeugt auch dynamische Felder für Solr
Es sollte geprüft werden, ob die Übertragung dynamischer Felder in der speziellen Anwendung erforderlich ist. Andernfalls sollte der Wert auf false gestellt werden.
MCR.Solr.ContentBaseFields eine Liste von Feldnamen für allgemeine Derivate-Metadaten
MCR.Solr.AVExtenderFields eine Liste von Feldnamen für Video-Derivate-Metadaten
MCR.Solr.TikaFields eine Liste von Feldnamen für Tika-Metadaten
MCR.Solr.JoinQueryFields enthält die Liste der Properties
MCR.Solr.ContentBaseFields , MCR.Solr.AVExtenderFields , MCR.Solr.TikaFields
MCR.Solr.NestedDocuments default=true;
aktiviert den Support für Nested Documents
MCR.Solr.ObserverConfigTypes default=requestHandler,searchComponent
MCR.Solr.HTTPResponseHeader.Content-Security-Policy das Property ist nicht gesetzt

Solr Kommandos für die MyCoRe CLI

Folgende Kommandos stehen für die Arbeit mit Solr an der Kommandozeile zur Verfügung. Bitte nachfolgendes unbedingt bei der Arbeit mit SOLR-Kommandos beachten: diese Kommandos sollten nur innerhalb der mycore.sh abgearbeitet werden, da es sonst dazu kommen kann, dass Operationen NICHT VOLLSTÄNDIG abgearbeitet werden! Bitte keine Batch-Jobs nutzen! Die Core ID für den Standard Solr Core in MyCoRe ist main.

show solr configuration
listet die aktuell konfigurierten Solr Cores auf.
register solr core with name {0} on server {1} as core {2}
registriert einen Solr Core mit dem Namen {0} (entspricht URL-Pfad des Cores auf dem Solr Server) auf dem Solr Server mit der Basis-URL {1} unter der ID {2} in der MyCoRe-Anwendung.
register solr core with name {0} as core {1}
registriert einen Solr Core mit dem Namen {0} (entspricht URL-Pfad des Cores auf dem Solr Server), auf dem Default Solr Server (siehe Property: MCR.Solr.ServerURL ) unter der ID {1} in der MyCoRe-Anwendung.
switch solr core {0} with core {1}
tauscht zwei bestehende Solr Cores in der Anwendung aus.
Dadurch wird es möglich, im laufenden Betrieb einen neuen Core zu konfigurieren und zu befüllen, um ihn anschließend gegen einen bestehenden Core auszutauschen.
reload solr configuration {0} in core {1}
lädt die Solr Konfiguration (und Schema) mit der ID {0} (aus allen verfügbaren MyCoRe Modulen und Komponenten) in den Solr Core mit der ID {1} .
rebuild solr metadata and content index in core {0}
lädt / aktualisiert die indexierten Metadaten und Inhalte aller MyCoRe-Objekte und Derivate im Solr Core mit der ID {0} .
rebuild solr metadata index for object {0} in core {1}
lädt / aktualisiert die indexierten Metadaten des MyCoRe-Objektes mit der ID {0} im Solr Core mit der ID {1} .
rebuild solr metadata index for all objects of type {0} in core {1}
lädt / aktualisiert die indexierten Metadaten aller MyCoRe-Objekte vom Typ {0} im Solr Core mit der ID {1} .
rebuild solr metadata index for selected in core {0}
lädt / aktualisiert die indexierten Metadaten für zuvor ausgewählten MyCoRe Objekte im Solr Core mit der ID {1}
(siehe Kommando select objects with solr query {0} in core {1} ).
rebuild solr metadata index in core {0}
lädt / aktualisiert die indexierten Metadaten für alle MyCoRe Objekte im Solr Core mit der ID {0} .
rebuild solr content index for object {0} in core {1}
lädt / aktualisiert die indexierten Inhalte aller Derivate des Objektes (oder des Derivates) {0} im Solr Core mit der ID {1} .
rebuild solr content index for selected in core {0}
lädt / aktualisiert die indexierten Inhalte der Derivate der ausgewählten Objekte (oder der ausgewählten Derivate) im Solr Core mit der ID {0} .
rebuild solr content index in core {0}
lädt / aktualisiert die indexierten Inhalte aller Derivate im Solr Core mit der ID {0} .
rebuild solr classification index in core {0}
lädt / aktualisiert die Klassifikations-Objekte im Solr Core mit der ID {0} .
clear solr index in core {0}
löscht alle Einträge aus dem Solr Core mit der ID {0} .
delete from solr index all objects of type {0} in core {1}
löscht alle Einträge für MyCoRe Objekte des Types {0} aus dem Solr Core mit der ID {1} .
delete from solr index object {0} in core {1}
löscht das MyCoRe Objekt mit der ID {0} aus dem Solr Core mit der ID {1} .
select objects with solr query {0} in core {1}
erzeugt eine Liste von MyCoRe-Objekten für die Solr Anfrage {0} im Solr Core mit der ID {1} .
Diese Liste kann anschließend mit weiteren Kommandos verarbeitet werden.
optimize solr index in core {0}
optimiert den Solr Core mit der ID {0} .
Mit dieser Operation werden Solr-intern stark fragmentierte Index-Segmente zusammengefasst.
synchronize solr metadata index for all objects of type {0} in core {1}
prüft, ob die Metadaten aller MyCoRe-Objekte des Types {0} im Solr Core mit der ID {1} indexiert worden sind und führt für fehlende Objekte eine Neuindexierung aus.
synchronize solr metadata index in core {0}
prüft, ob die Metadaten aller MyCoRe-Objekte im Solr Core mit der ID {0} indexiert worden sind und führt für fehlende Objekte eine Neuindexierung aus.

Solr-Abfragen über die MyCoRe-Java-API

Mit diesem Code-Schnipsel soll demonstriert werden, wie ein Zugriff auf die Solr-Daten mittels MyCoRe-API erfolgen kann.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.common.SolrDocumentList;

 import org.mycore.solr.MCRSolrClientFactory;
 import org.mycore.solr.MCRSolrUtils;

 ...
 SolrClient solrClient = MCRSolrClientFactory.getMainSolrClient();

  //oder:
 SolrClient solrClient = MCRSolrClientFactory.get("{coreID}").getClient();

 SolrQuery query = new SolrQuery();
 query.setQuery("title:foo");
 query.setRows(10);
 SolrDocumentList results = solrClient.query(query).getResults();
 ...