Zielgruppe EntwicklungVersion: GSB 7Servicesuche
Bitte beachten: Diese Informationen beziehen sich auf den GSB 7 und werden aktuell überarbeitet!
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 und der Template-Sprache Velocity nötig.
Aufbau des Formulars
Für Details, wie man ein Formular aufbaut, sei auf die Dokumentation von Formularen 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 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.
- id_ - Wird zum laden der CoreMedia-Inhalte gebraucht
- content - Der zusammengefasste Inhalt eines Dokuments
- score - Die von Solr berechnete Relevanz
- 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.
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)
- 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"
- Tabellenlayout (layout)
- /standardlsg/.../Layout_SearchResult - Velocity-Template für die generierung der HTML-Ausgabe
- Einträge pro Seite (resultsPerPage) - Im Template für die Paginierung des Suchergebnisses benutzt
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:
## display the page numbers and label for result index#set( $firstResultIndex= $slot.firstEntryIndex+1 )#set( $lastResultIndex= $slot.lastEntryIndex+1 )#if( $slot.numPages > 1 )<p>$cms.message("SuchResultate",$firstResultIndex,$lastResultIndex,$slot.numTotalEntries)</p> <ul id="searchResultIndex" class="navIndex"> #if( $slot.pageIndex > 1) #set( $iPageLink= $slot.pageIndex - 1 ) <li class="back"> <a href="$slot.getPageLink($iPageLink)" title="$cms.message("SucheSeite", "$iPageLink")"> <img src="$cms.link($bild_zurueck.normal)" alt="$cms.message("PfeilLinks")" /> </a></li> #end #foreach( $page in $slot.getPageNumbersExtract(1,2,2,1)) #if( $slot.pageIndex == $page) <li #if($slot.pageIndex==1) class="first"#end> <strong title="$cms.message("SucheSieSindHier", "$page")">$page</strong> </li> #elseif( $page == 0 ) <li> … </li> #else <li><a href="$slot.getPageLink($page)" title="$cms.message("SucheSeite", "$page")">$page</a></li> #end #end #if( $slot.pageIndex < $slot.numPages) #set( $iPageLink= $slot.pageIndex + 1 ) <li class="forward"> <a href="$slot.getPageLink($iPageLink)" title="$cms.message("SucheSeite", "$iPageLink")"> <img src="$cms.link($bild_weiter.normal)" alt="$cms.message("PfeilRechts")" /> </a> </li> #end </ul>#end
- Ausgabe eines Tabellenkopfes mit der Möglichkeit, die Ergebnisse nachträglich umzusortieren:
## display sort links<p>$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") ) <span><a href="$sLink" title="$linkLabel" class="sortUp">$cms.escapeXml($titleLabel)</a></span> #end #if( ($slot.currentSortOrder == "dateOfIssue_dt asc" ) ) #set( $sLink = $slot.getSortOrderLink("dateOfIssue_dt desc") ) #set( $linkLabel = $cms.message("AbsteigendSortieren") ) <span><a href="$sLink" title="$linkLabel" class="sortDown">$cms.escapeXml($titleLabel)</a></span> #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") ) <span><a href="$sLink" title="$linkLabel" class="sortUp">$cms.escapeXml($titleLabel)</a></span> #end #if( ($slot.currentSortOrder == "score asc" ) ) #set( $sLink = $slot.getSortOrderLink("score desc") ) #set( $linkLabel = $cms.message("AbsteigendSortieren") ) <span><a href="$sLink" title="$linkLabel" class="sortDown">$cms.escapeXml($titleLabel)</a></span> #end</p>
- Ausgabe der Ergebniszeile(n):
<ol id="searchResult" class="links">#set($firstIndex = $slot.firstEntryIndex)#foreach( $entry in $slot.entries ) #set($currentIndex = $firstIndex + $velocityCount) <li>${currentIndex}. - <em title="Relevanz: ${entry.Wrapper.PercentalScore}%" class="relevance relevance${entry.Wrapper.PercentalScore}"> Relevanz: ${entry.Wrapper.PercentalScore}% </em> $cms.include($entry.Wrapper.LanguageEnt, "renderSearchResultHighlighted",["wrapper", $entry.Wrapper]) </li>#end</ol>