Version: GSB 7Solr
Die Implementierung der Suche lässt sich in zwei Bereiche unterteilen:
- In die Indizierung der Inhalte und
- das eigentliche Abfragen der Inhalte nach bestimmten Suchkriterien.
Indizierung der Inhalte
Die Indizierung der Inhalte wird im GSB mit einem eigenständigen, Spring-basierten und über die Unified-API mit dem Repository kommunizierenden Indexerclient zur Vefügung gestellt.
Durch den Vorgang der Indizierung werden die im CMS vorhandenen Inhalte so aufbereitet, dass eine effiziente Filterung nach bestimmten Suchkriterien ermöglicht wird. Dabei wird eine Kopie des zu indizierenden Dokumentes angelegt, das im Folgenden mit „Index-Document“ bezeichnet wird.
Hierzu ist eine Liste derjenigen Dokumenttypen anzugeben, die überhaupt indiziert, d.h. der Suche als mögliche Ergebnisse zur Verfügung gestellt werden sollen. Es ist nicht sinnvoll, sämtliche Dokumenttypen zu indizieren, da hierdurch auch Dokumenttypen, die keinerlei Inhalt tragen (z. B. HTML-Formularelemente, Style-Elemente, Konfigurationsdokumente etc.) in den Index aufgenommen würden. Diese sind als Ergebnis einer Suche nicht erwünscht.
Zu indizierende Dokumenttypen
Die Angabe der zu indizierenden Dokumenttypen erfolgt in der Spring Konfiguration indexer-common.xml des Indexerclients (basis/config/Indexer/config). Darin wird eine Springbean baseIndexer definiert mit der Property "includedDocTypes". Dieses Bean wird dann in einer mandantespezifischen Konfiguration (siehe als Beispiel dafür in der standardlsg unter config/Indexer/config/standardlsg-lucene-indexer.xml) erweitert. Wenn also entsprechende Konfigurationen geändert werden sollen, bspw. um etwa den Dokumenttyp Announcement nicht mehr zu indizieren, so kann in dem erweiterenden Bean (hier "standardlsgIndexer") das Property includedDocTypes mit den gewünschten Werten überschrieben werden.
Es werden standardmäßig die folgenden Dokumenttypen indiziert:
- Address
- Announcement
- Audio
- Basepage
- CallForBids
- ContactData
- CourtDecision
- Crew
- Directions
- Disposal
- DisposalImmo
- DocumentCategory
- DocumentLeaf
- Employee
- Event
- ExternalLink
- FAQ
- FAQList
- Flyer
- GCApplication
- GCBook
- GCJournal
- GCPresentation
- GCPrintout
- GenericCollection
- GlossarEntry
- Glossary
- HTMLFragment
- IMGMap
- IMGObject
- Imprint
- Interview
- ItemGallery
- JobOffer
- Law
- LinkGallery
- Location
- Memorandum
- News
- Newsletter
- OrganisationalUnit
- PBApplication
- PBBook
- PBForm
- PBHandout
- PBJournal
- PBPresentation
- PBPrintout
- PBTemplate
- PRDocument
- PressMirror
- PressRelease
- Product
- Project
- Publication
- RentalImmo
- Report
- RespTarget
- ServiceCompst
- ServiceContact
- ServiceLocation
- ServiceOffer
- ServiceOfferIT
- Services
- SLConditions
- Speech
- Task
- Team
- TextFragment
- Video
- Vita
In allen diesen Dokumenttypen kann über die Property shouldNotBeIndexed das individuelle Dokument als ein unerwünschtes Suchergebnis gekennzeichnet werden. Das Dokument wird dann entsprechend nicht in den Index aufgenommen.
Ein weiterer möglicher Wert für das Property shouldNotBeIndexed ist "2": Dies bedeutet, dass zwar das Dokument indiziert wird, etwaige Blobs aber ignoriert werden, so werden dann entsprechend PDF-Inhalte o.Ä. nicht in den Index geschrieben.
Konkretes Vorgehen
Beim Indizieren wird keine exakte Kopie erzeugt, sondern es wird für jede Property des Original-Dokuments während des Indizierungsprozesses angegeben, ob sie indiziert, tokenisiert (engl. tokenized) oder gespeichert werden soll. Pro Property eines Dokuments kann eine beliebige Kombination der drei genannten Indizierungsdirektiven festgelegt werden. Diese drei Optionen werden im Folgenden ausführlich beschrieben.
Indizieren
Wird nun ein Dokument indiziert, so wird es mitsamt seiner Properties als Vorlage für ein "Index-Document" genommen, das als Abbild des Original-Dokuments im Index erzeugt wird. Jede Property eines CoreMedia-Dokuments wird auf ein sogenanntes "Field" des erzeugten „Index-Documents" abgebildet.
Der GSB bietet auch die Möglichkeit, extern abgelegte Download-Dokumente mit in den Suchindex aufzunehmen.
Damit der Inhalt einer Property überhaupt durchsuchbar wird, muss er indiziert werden.
Tokenisieren
Darüber hinaus kann entschieden werden, ob der Inhalt auch tokenisiert werden soll, d.h. sollen die einzelnen Worte (engl. tokens) eines Textes separat gespeichert werden oder nicht. Das Tokenisieren eines Textes hat gegenüber der Speicherung des Gesamttextes den Vorteil, dass die Größe des Indexes nicht unnötig wächst, da ein Token nicht mehrfach gespeichert wird, sondern Referenzen auf ein einmalig gespeichertes Token verwendet werden, abgesehen davon ist eine Tokenisierung natürlich auch notwendig, um eine sinnvolle Volltextsuche anbieten zu können. Dies kann je nach Indexerausprägung (Solr, Lucene) konfiguriert werden. Solr bietet dafür Konfigurationsmöglichkeiten in der schema.xml der Applikation, welche im Ordner basis/config/solr/multicore/MANDANT/config zu finden ist. Diese Datei kann im jeweiligen Mandantenordner überschrieben werden. Für Lucene wird dies standardmäßig in der Datei config/Indexer/config/indexer-lucene.xml durchgeführt. Änderungen müssen dann in der mandantenspezifischen Konfiguration vorgenommen werden, indem die entsprechenden Beans überschrieben werden.
Konkret kann in der Bean luceneFieldTokenizer u.a. folgende Einstellung vorgenommen werden:
- tokenizeProperties: Angage einer Liste von zu tokenisierenden Dokumentproperties
Speichern
Die Speicherung der Property eines Dokuments erlangt dann besondere Bedeutung, wenn ihr Inhalt im Suchergebnis direkt zur Verfügung stehen soll. Dies ist z. B. der Fall für die Id eines Dokuments, da über diese Id auf das Original-Dokument im CoreMedia-Repository zugegriffen werden kann und somit alle weiteren Properties zur Verfügung stehen. Weitere Properties können zur Speicherung in Frage kommen, wenn sie direkt nach der Suche im Suchergebnis angezeigt werden sollen, ohne dass ein weiterer Zugriff auf das Repository erfolgen soll. Außerdem müssen alle Properties, die als Sortierkriterium dienen sollen, gespeichert werden.
Standardmäßig werden
- alle Properties indiziert
- Blob-, XML- und LinkList-Properties werden nicht gespeichert
- Date und Integer-Properties werden nicht tokenisiert
Dieses Verhalten kann je nach Indexerauspägung konfiguriert werden. Während die relevanten Einstellungen bei Solr in der schema.xml vorgenommen werden, also mit den Mitteln des Produkts Solr, können für die Lucene Implementierung im IndexerClient ebenfalls entsprechende Einstellungen vorgenommen werden. Dies geschieht zunächst in der Spring-Konfigurationsdatei indexer-lucene.xml, oder in einer mandantenspezifischen Konfiguration, die die relevanten Beans erweitert, oder ersetzt.
Die Speicherung von Properties kann in der Bean luceneFieldStore konfiguriert werden:
- shouldStoreDataType: Bspw. alles Strings sollen gespeichert werden
- shouldStoreProperties: Explizite Angabe von zu speichernden Properties
Weitere Properties
Neben allen Properties eines CoreMedia-Dokuments werden noch weitere Properties zum indizierten Abbild des Dokuments, also weitere „Fields“/Felder zum „Index Document“ hinzugefügt. Dies geschieht in der Java-Klasse de.materna.cms.indexer.mapper.ContentMapper.
Die Namen der Felder des „Index-Documents“ wie auch die Namen der Properties des Originaldokumentes sind als Klassenvariablen/Konstanten in der Javaklasse de.materna.cms.indexer.util.IndexerConfigConstants hinterlegt. Hier werden jeweils der Name der Konstanten in GROSSBUCHSTABEN und deren aktueller Wert angegeben.
Im wesentlichen werden dabei die folgenden Felder mit in das Index Document übernommen:
- INDEXER_COREMEDIA_COREPROPERTY_CONTENT_ID = "id_": Die ID des Dokuments
- INDEXER_COREMEDIA_COREPROPERTY_CUSTOMER = "customer_": Der Name des Mandanten
- INDEXER_COREMEDIA_COREPROPERTY_DOCUMENT_TYPE = "documentType_": Der Dokumenttyp
- INDEXER_COREMEDIA_COREPROPERTY_FOLDER_ID = "folderId_": Die ID des Ordners, in dem sich das Dokument befindet
- INDEXER_COREMEDIA_COREPROPERTY_FOLDER_PATH = "folderPath_": Der Pfad des Ordners
- INDEXER_COREMEDIA_COREPROPERTY_LANGUAGE = "language_": Die ermittelte Sprachkennzeichnung
- INDEXER_COREMEDIA_COREPROPERTY_MODIFICATION_DATE = "modificationDate_": Das Modifikationsdatum des Dokumentes
- INDEXER_COREMEDIA_COREPROPERTY_NAME = "name_": Der Name des Dokumentes
- INDEXER_COREMEDIA_COREPROPERTY_PATH = "path_": Der Pfad zum Dokument (Im Lucene Indexer ist der Dokumentname per Default nicht enthalten -> Stichwort TooManyClausesCountException)
Dynamische/virtuelle Properties
Neben den statischen im Dokumentenmodell registrierten Properties gibt es die Möglichkeit zur Laufzeit dynamische/virtuelle Properties zu einzelnen Dokumenten hinzuzufügen. Dies geschieht über die GSB-spezifische Property „ClassifiedLinkList“, in denen im Gegensatz zu den üblichen LinkList-Properties zu jeder Liste noch ein String-Classifier oder ein Link-Classifier hinzugefügt werden kann. ClassifiedLinkListen bestehen also aus drei Elementen:
- dem Text-Classifier
- dem Link-Classifier
- der LinkList
Jede ClassifiedLinkList Property deren Name in der config/Indexer/config/indexer-common.xml in der Spring BeanbaseContentMapper im Attribut cl2VirtualProperties registriert ist, wird wie folgt behandelt
- Aus einer ClassifiedLinkList werden im allgemeinen mehrere virtuelle Fields im Index erzeugt
- der Name der ClassifiedLinkList wird als Präfix aller dieser Fieldnamen verwendet. Dies ist der technische Name der Property und NICHT der evtl. angepasste, im Java-Editor angezeigt Name. (Beispiel: cl2RespTargets)
- ist ein Dokument in der LinkClassifier Property verlinkt, so wird dessen Title-Property ausgelesen, evtl. enthaltenen Leerzeichen werden durch # ersetzt und der entstandene String an das obige Namens-Präfix getrennt durch einen Unterstrich angehängt, um letztendlich den Namen des Fields zu ergeben (Beispiel: Titel des LinkClassifiers ist „Mein Titel“, dann wird zusammen mit obigem Beispiel ein Field mit Namen cl2RespTargets_Mein#Titel erzeugt)
- als Wert dieses Fields wird der Wert der „Title“-Property aller Dokumente in der LinkList. Die einzelnen Titel werden durch Leerzeichen getrennt verwendet (Beispiel: Ist der Titel des ersten verlinkten Dokumentes in der LinkList „Sport aus NRW“, so wird zusammen mit obigem Beispiel das Field cl2RespTargets_Mein#Titel: Sport aus NRW) im Index erzeugt
- ist der LinkClassifier nicht gesetzt wird der TextClassifier ausgelesen und exakt wie die Title-Property des LinkClassifiers behandelt
- ist weder link-, noch TextClassifier gesetzt, wird ein Field mit Namen cl2RespTargets angelegt
- sind Text- und LinkClassifier gesetzt, aber die LinkList leer, wird der TextClassifier als Inhalt verwendet und der LinkClassifier wie oben beschrieben behandelt.
- Sind LinkClassifier und LinkList leer, allerdings der TextClassifier gesetzt, so wird eine leere Property angelegt (Beispiel: TextClassifier: „Fussball“, so entsteht das Field cl2RespTargets_Fussball)
Alle so entstandenen Fields werden als Strings behandelt und sowohl indiziert, tokenisiert als auch gespeichert. Sie stehen also für eine Sortierung zur Verfügung.
Ein Sonderfall stellt die ClassifiedLinkList Property cl2Taxonomies dar. Diese wird für die Realisierung von Taxonomien also hierarchischen Dokumentkategorien genutzt. Bei der Indizierung der in Linklist verlinkten Dokumente wird nicht der Wert der Title-Property, sondern der Dokumentpfad indiziert. Hierarchien lassen sich also durch eine entsprechende Ablagestruktur der Dokumentkategorien erzeugen.
Abfrage/Suche
Für die Suche existieren konsequenterweise auch zwei Ansätze, je nachdem, ob es sich um einen Lucene-Index, oder einen Solr-Index handelt, der verwendet werden soll.Die zugehörige Dokumentation findet sich auf den folgenden Seiten:
- Solr-Suche
- Lucene-Suche