Version: GSB 7Servicesuche
In diesem Artikel wird die Konfiguration einer einfachen Schlagwortsuche am Beispiel der Servicesuche der Standardlösung erläutert. Dabei werden einige Konfiguration erst einmal ignoriert, da diese nur für die Expertensuche wichig sind und dort erklärt werden. Zum Verständnis der kompletten Konfiguration sind Kenntnisse der Solr-Query-Syntax / Lucene-Query-Syntax und der Template-Sprache Velocity nötig.
Aufbau des Formulars
Für Details, wie man ein Formular aufbaut, sei auf die Dokumentation des Formularbaukastens hingewiesen, hier wird nur noch einmal kurz der Grundaufbau dargestellt.
Für die Darstellung eines Formulars wird als erstes ein Integrator gebraucht, welcher in der Standardlösung wie auf den folgenden Bildern konfiguriert ist.
Die Integrator Konfiguration:
Die Integrator Meta-Informationen:
Das eigentliche Formular, welches im Integrator verlinkt ist, sieht folgendermassen aus:
Dabei sind folgende Konfigurationen für diese Beschreibung wichtig:
- Formularelemente - Ein Textfeld für den Suchbegriff, ein verstecktes Feld für die Sortierung der Suchergebnisse und der Submit-Button für die Ausführung der Suche.
- Aktion - Die Konfigurierte Formular-Action, hier die Expertensuche
- Formularverarbeitungsreferenz - Verknüpfung zu den Seiten für die Suchdarstellung im Erfolgs-/FehlerFall
Konfiguration der Felder
Aus dem Textfeld werden zwei Konfigurationsparameter für die Konfiguration der Suche wichtig.
Die ID (hier "templateQueryString") gibt an, über welchen Namen der Inhalt des Textfeldes in der Suche angesprochen werden kann, der Standardwert (hier "Suchbegriff") ist wichtig, damit man in der Such-Action die Suche nach diesem Ausschliessen kann.
Die gleichen Parameter sind auch bei dem versteckten Feld für die Sortierung wichtig.
Dabei ist der Wert "sortOrder" ein spezieller Wert, welcher durch das System automatisch ausgewertet wird. Man muss diesen nicht noch extra in der Konfiguration der Such-Action berücksichtigen. Der hier gesetzte Standardwert "score desc" sagt aus, dass das Suchergebniss absteigend (descending) nach der Relevanz (score) ausgegeben werden soll.
Konfiguration der Such-Action
Für die Servicesuche wird die gleiche Such-Action benutzt wie für die Expertensuche. Im Rahmen dieser Beschreibung wird nur auf die Parameter, die für die Servicesuche relevant sind eingegangen. Die anderen Parameter werden dann mit der Expertensuche erklärt.
Für die Konfiguration der Suche mit Solr ist die Java-Klasse de.materna.cms.cae.forms.action.SolrQueryAction zu benutzen. Die Parameter (parameters und cl2Parameters) werden als Velocity-Template konfiguriert und von der SolrQueryAction verarbeitet. Prinzipiell können alle für eine Suche wichtigen Konfigurationen direkt in der Action angegeben werden, für häufig verwendete Konfigurationen, die in fast allen Suchen gebraucht werden ist es allerdings besser, diese in Suchkonfigurationsstrings (ConfigRichText10) auszulagern und als QueryParameter in den cl2Parameters zu verlinken. Für die Suche der wichtigste und für die Servicesuche auch der einzige Interessante Parameter ist an dieser Stelle solr.q = $!solr_templateQueryStringExtended. Mit solr.q übergibt man die Suchanfrage in Solr-Query-Syntax / Lucene-Query-Syntax an den Such-Server. Die als Velocity-String $!solr_templateQueryStringExtended übergebene Suche wird im Dokument Mapping/Textfelder aus dem im Request übergebenen Suchparameter templateQueryString zusammengesetz.
Durch das Mapping wird aus templateQueryString für die Suche der Ausdruck $solr_templateQueryStringExtended = "{!type=edismax mm=100% qf='content^1 keywords_str^3'}$templateQueryString". Über die sogennanten lokalen Suchparameter in geschweiften Klammern wird festgelegt, wie die Relevanz berechnet werden soll. Die Werte hier bedeuten folgendes:
- type=edismax -> Der Algorithmus, der zur Berechnung der Relevanz (score) benutzt wird
- qf='content^1 keywords_str^3' -> Es soll in den Feldern content und keywords_str gesucht werden. Dabei soll der Algorithmus das Auffinden der Suchwörter im Feld keywords_str für die Relevanz 3 mal höher bewerten als im Feld content.
- mm=100% -> Der Suchbegriff muss auf jeden Fall in einem der beiden Felder gefunden werden.
Zusätzlich zum Mappen des Suchbegriffs wird auch noch aus dem Dokument Konfiguration/Allgemein die Grundkonfiguration für die Suche benutzt.
Die einzelnen Parameter bedeuten folgendes:
- solr.fl - Die Felder, die Solr aus dem Index zurückgibt.
- solr.rows - Die maximale Anzahl an Treffern, die Solr zurückliefert.
- solr.sort - Das Standardfeld, nach dem Sortiert werden soll, falls nichts im Request übergeben wurde
- searchArchive - wie archivierte Dokumente gefunden werden sollen (0 = alle, 1 = nur archivierte, 2 = nur nicht archivierte)
- searchIssued - wie veröffentlichte Dokumente gefunden werden sollen (0 = alle, 1 = nur veröffentlichte, 2 = nur nicht veröffentlichte)
- optimizeForTables -
- useSessionCache -
- inhibitSearch - Kommaseparierte Liste von Parameter-Wert-Kombinationen, die eine Ausführung der Suche verhindern, falls der Standardsuchbegriff abgeschickt wurde.
- id_ - Wird zum laden der CoreMedia-Inhalte gebraucht
- content - Der zusammengefasste Inhalt eines Dokuments
- score - Die von Solr berechnete Relevanz
Hinweis: Die letzte Interessante Konfiguration bei den cl2Parameters ist der verlinkte GenericTable Solr_Ergebnis vom Typ list und als QueryResultTable klassifiziert. Diese Konfiguration ist intern für eine optimierte Ergebnisausgabe verantwortlich und sollte für bessere Perfomanz gesetzt werden.
Ergebnis-Darstellung
Für die Ergebnisdarstellung der Suche ist folgende Dokumentenhierarchie verantwortlich, die im Servicesuche-Formular sowohl für Erfolgs- (success) wie Fehlerfall (failure) eingehängt ist:
/ success/failure target : /standarlsg/DE/Service/Suche/suche_node
|-- target : /standarlsg/DE/Service/Suche/suche_target
| |-- content : /standarlsg/SiteGlobals/Forms/Expertensuche_Integrator
| | |-- formular : /standarlsg/SiteGlobals/Forms/Expertensuche_Formular
| | | `-- searchResultTable : /standarlsg/SiteGlobals/Functions/Solr/Suche/Ergebnisdarstellung/Expertensuche/Solr_Ergebnis
| | | |-- list : /standarlsg/SiteGlobals/Functions/Solr/Suche/Ergebnisdarstellung/Expertensuche/Solr_Ergebnis_Set
| | | |-- meintenSie : /standarlsg/SiteGlobals/Functions/Solr/Suche/Ergebnisdarstellung/MeintenSie_TemplateQueryString
| | | `-- layout : /standarlsg/SiteGlobals/Layout/ContentRegion/Tabellen/Layout_SearchResult
| | `-- layout : /standarlsg/SiteGlobals/Layout/Formulare/Layout_Expertensuche
| `-- supplement : /standarlsg/SiteGlobals/Functions/Solr/Suche/Ergebnisdarstellung/Expertensuche/Facettierung
| `-- layout : /standarlsg/SiteGlobals/Layout/Views/GenericJSP/Facets
Für die grundsätzliche Darstellung der Ergebnisse der Servicesuche ist dabei der im Expertensuche-Formular eingehängte GenericTable Solr_Ergebnis. (Das Dokument, welches auch in der Action eingehangen ist.)
Die Konfiguration im Detail:
- Darzustellende Inhalte (cl2relatedEnts)
- Tabellenlayout (layout)
- Einträge pro Seite (resultsPerPage) - Im Template für die Paginierung des Suchergebnisses benutzt
- Slotbelegung list - Name des slots im Velocity-Template (layout)
- Layout /standardlsg/.../renderSearchResult - Die View zum Einbinden des Suchergebnisses
- Dokument /standardlsg/.../Solr_Ergebnis_Set - Das einzubindende Objekt (GenericResultSet) für das Velocity-Template (layout)
- Slotbelegung meintenSie - Template für die Anzeige alternativer Suchbegriffe. Erklärung siehe Meinten Sie
- /standardlsg/.../Layout_SearchResult - Velocity-Template für die generierung der HTML-Ausgabe
Für die Servicesuche ist vor allem das Tabellenlayout interessant, weil an dieser Stelle konkret die Ergebnisse rausgeschrieben werden. Dabei werden verschiedene Teile behandelt.
- Ausgabe der Paginierung:
<syntaxhighlight lang="xml" enclose="div">
- set( $firstResultIndex= $slot.firstEntryIndex+1 )
- set( $lastResultIndex= $slot.lastEntryIndex+1 )
- if( $slot.numPages > 1 )
- display the page numbers and label for result index
$cms.message("SuchResultate",$firstResultIndex,$lastResultIndex,$slot.numTotalEntries)
- <a href="$slot.getPageLink($iPageLink)" title="$cms.message("SucheSeite", "$iPageLink")"> <img src="$cms.link($bild_zurueck.normal)" alt="$cms.message("PfeilLinks")" /> </a>
#end
#foreach( $page in $slot.getPageNumbersExtract(1,2,2,1))
#if( $slot.pageIndex == $page)
- $page
#elseif( $page == 0 )
- …
#else
- <a href="$slot.getPageLink($page)" title="$cms.message("SucheSeite", "$page")">$page</a>
#end
#end
#if( $slot.pageIndex < $slot.numPages)
#set( $iPageLink= $slot.pageIndex + 1 )
- <a href="$slot.getPageLink($iPageLink)" title="$cms.message("SucheSeite", "$iPageLink")"> <img src="$cms.link($bild_weiter.normal)" alt="$cms.message("PfeilRechts")" /> </a>
#end
- end
</syntaxhighlight>
- Ausgabe eines Tabellenkopfes mit der Möglichkeit, die Ergebnisse nachträglich umzusortieren:
<syntaxhighlight lang="xml" enclose="div">
- display sort links
$cms.message("Sortierung") ## Nach Titel sortieren #set( $titleLabel = $cms.message("Titel") ) #if( ($slot.currentSortOrder == "") || ( $slot.currentSortOrder != "title_text_sort asc" ) ) #set( $sLink = $slot.getSortOrderLink("title_text_sort asc") ) #set( $linkLabel = $cms.message("AufsteigendSortieren") ) <a href="$sLink" title="$linkLabel" class="sortUp">$cms.escapeXml($titleLabel)</a> #end #if( ($slot.currentSortOrder == "title_text_sort asc" ) ) #set( $sLink = $slot.getSortOrderLink("title_text_sort desc") ) #set( $linkLabel = $cms.message("AbsteigendSortieren") ) <a href="$sLink" title="$linkLabel" class="sortDown">$cms.escapeXml($titleLabel)</a> #end ## Nach Datum sortieren #set( $titleLabel = $cms.message("Datum") ) #if( ($slot.currentSortOrder == "") || ( $slot.currentSortOrder != "dateOfIssue_dt asc" ) ) #set( $sLink = $slot.getSortOrderLink("dateOfIssue_dt asc") ) #set( $linkLabel = $cms.message("AufsteigendSortieren") ) <a href="$sLink" title="$linkLabel" class="sortUp">$cms.escapeXml($titleLabel)</a> #end #if( ($slot.currentSortOrder == "dateOfIssue_dt asc" ) ) #set( $sLink = $slot.getSortOrderLink("dateOfIssue_dt desc") ) #set( $linkLabel = $cms.message("AbsteigendSortieren") ) <a href="$sLink" title="$linkLabel" class="sortDown">$cms.escapeXml($titleLabel)</a> #end ## Nach Relevanz sortieren #set( $titleLabel = $cms.message("Relevanz") ) #if( ($slot.currentSortOrder == "") || ( $slot.currentSortOrder != "score asc" ) ) #set( $sLink = $slot.getSortOrderLink("score asc") ) #set( $linkLabel = $cms.message("AufsteigendSortieren") ) <a href="$sLink" title="$linkLabel" class="sortUp">$cms.escapeXml($titleLabel)</a> #end #if( ($slot.currentSortOrder == "score asc" ) ) #set( $sLink = $slot.getSortOrderLink("score desc") ) #set( $linkLabel = $cms.message("AbsteigendSortieren") ) <a href="$sLink" title="$linkLabel" class="sortDown">$cms.escapeXml($titleLabel)</a> #end
</syntaxhighlight>
- Ausgabe der Ergebniszeile(n):
<syntaxhighlight lang="xml" enclose="div">
#set($currentIndex = $firstIndex + $velocityCount)
- ${currentIndex}. - Relevanz: ${entry.Wrapper.PercentalScore}% $cms.include($entry.Wrapper.LanguageEnt, "renderSearchResultHighlighted",["wrapper", $entry.Wrapper])
- set($firstIndex = $slot.firstEntryIndex)
- foreach( $entry in $slot.entries )
- end
</syntaxhighlight>