Version: GSB 7Lucene
Besonderheiten
Lucene hat mit der Version 1.4 eine Obergrenze für sogenannte BooleanClauses eingeführt und wirft eine TooManyBooleanClausesException, wenn diese Grenze überschritten wird. BooleanClauses werden während der Suche bei der Analyse der Suchanfrage intern erzeugt. Insbesondere Suchen innerhalb eines Intervalls (RangeQueries) und Suchen mit Wildcards wie * und ? führen leicht zur Überschreitung des Default-Wertes von 1024 BooleanClauses.
Betrachten wir einmal die Suche nach einem Dokument innerhalb eines bestimmten Pfads über folgende Anfrage
title:GSB AND path_:/sites/standardlsg/content*
Die Anfrage wurde in der Syntax des Parameters searchEngineQueryString formuliert, d.h. in der Lucene-Query-Snytax. Eine äquivalente Anfrage würde intern erzeugt werden, wenn Sie ein Suchformular mit den Parametern
title=GSBpath=/Sites/standardlsg/Content
an die Searcher-Komponente absenden würden. Beachten Sie hierbei die automatische Abbildung des Request-Parameters path auf das indizierte Field path_, das Hinzufügen der Wildcard * und die Konvertierung in Kleinbuchstaben, die durch die Searcher-Komponente für den Parameter path durchgeführt wird!
Abhängig von der Anzahl der indizierten Dokumente, deren Eintrag im path_-Field mit /sites/standardlsg/content beginnt, wird die Anfrage in etwa in der folgenden Form expandiert
<syntaxhighlight lang="xml" enclose="div"> title:GSB AND (path_:/sites/standardlsg/content OR path_:/sites/standardlsg/content/news/news1 OR path_:/sites/standardlsg/content/news/news2 …) </syntaxhighlight>
Es wird also jeder path_ Eintrag eines Dokumentes, das dem angegebenen Muster path_:/sites/standardlsg/content* entspricht, per OR an die auszuführende Suchanfrage angehängt.
Liegen nun mehr als 1024 Dokumente unterhalb von /Sites/standardlsg/Content/ oder unterhalb eines der Unterverzeichnisse, dann bricht die Suche mit einer TooManyBooleanClausesException ab.
Um das genannten Probleme zu umgehen können folgende Möglichkeiten in betracht gezogen werden:
- die Grenze von 1024 BooleanClauses anheben
- dafür Sorge zu tragen, dass bei der Expandierung von Wildcard- und Intervall-Suchen nicht exzessiv viele OR-Verknüpfungen generiert werden
Möglichkeit 1. lässt sich in den build_tomcat.properties über foglende Property verwirklichen:
tomcat_jvm_parameters= -Dorg.apache.lucene.maxClauseCount=100000
Da die Anzahl der tatsächlich verwendeten BooleanClauses von der Anzahl der indizierten Dokumente abhängt, muss dieser Wert bei wachsendem Index bei Bedarf angepasst werden.
Hierbei ist allerdings zu beachten, dass das Limit von 1024 zur Vermeidung von OutOfMemoryException eingeführt wurde, eine Anhebung also genau zu diesen Problemen führen kann. Bei OutOfMermoryExceptions spielen die konfigurierten Generator-Cache-Größen, die ebenfalls einen Anteil an der Java-Heap-Size, verwenden ebenfalls eine Rolle. In der Praxis muss man also eine Balance dieser Werte finden. Die vorgegebenen Einstellungen haben sich bisher als brauchbare Ausgangswerte erwiesen.
Möglichkeit 2.:
In der indexer-lucene.xml Sprinkonfiguration die Property excludeDocumentNameInPath auf true stellen (ist aber auch der Default)
Als besonders fehlerträchtig haben sich Pfad-Suchen erwiesen. Dadurch, dass man den Namen der Dokumente nicht mehr in das Field path_ indiziert, wird die Anzahl der verschiedenen path_-Einträge reduziert. Sie wächst nun nicht mehr mit der Anzahl der Dokumente, sondern mit der Anzahl der Verzeichnisse.
Dies verhindert die TooManyBooleanClausesException in den meisten Fällen. Sollte allerdings z. B. eine großräumige Intervall-Suche nach der CoreMedia-ID id_ durchgeführt werden, stößt dieser Ansatz an seine Grenzen, da die ID naturgemäß für alle Dokumente unterschiedlich sein muss.
DynDocSearchEnt
Mit Hilfe eines DynDocSearchEnt Dokumentes kann dynamisch mit Hilfe eines Suchausdrucks eine Kollektion von GSB Dokumenten zusammengestellt werden. In Kombination mit einer generischen Tabelle können hierdurch auf einfache Art und Weise Inhalte einer Webseite zusammengestellt werden.
Konfiguration / Properties
In der nachfolgenden Tabelle werden die Properties der DynDocSearchEnt Dokumente aufgeführt.
Property | Funktion |
maxResults | Gibt die maximale Anzahl der zurückzuliefernden Dokumente an. Die eigentliche Suche wird dadurch nicht beeinflusst, um eine eventuelle Sortierung nicht zu beeinträchtigen.
Wenn ein Wert < 1 angegeben wird, wird der Defaultwert 100 genommen. |
maxLuceneResults | Gibt die maximale Anzahl der vom Lucene zu berücksichtigenden Dokumente an. Wenn mehr als diese Anzahl gefunden werden, wird eine BundOnlineTooManySearchResultsException geworfen und gar nichts zurückgeliefert.
Wenn ein Wert < 1 angegeben wird, wird der Defaultwert 500 genommen. |
searchFolders | Es werden nur Dokumente unterhalb der hier angegebenen Folder berücksichtigt.
Der Defaultwert ist der Root-Folder des aktuellen Mandanten. |
includeSubFolders | Gibt an, ob auch Sub-Folder rekursiv durchsucht werden sollen. |
searchByFolderID | Gibt an, ob der zugehörige Folder der Dokumente anhand des Dokumentpfades oder der Folder-ID ermittelt werden soll. |
includeDocTypes | Es wird nur nach den hier angegebenen Dokument-Typen gesucht.
Die einzelnen Typen werden durch Komma, Semikolon oder Leerzeichen getrennt. |
includeSubTypes | Wenn hier ein wahrer Wert angegeben wird, so werden auch Untertypen der includeDocTypes genannten Dokumenttypen bei der Suche berücksichtigt. |
excludeDocTypes | Hier können einzelne der Untertypen wieder ausgeschlossen werden, wenn includeSubTypes true ist. |
searchCurrentDocs | Hier sind drei verschiedene Werte möglich:
Wert 0: Das Attribut dateOfIssue wird nicht in der Query berücksichtigt. Es werden also bzgl. dieses Datums alle Dokumente in das Suchergebnis aufgenommen. Wert 1: Es werden ausschließlich die bereits "erschienenen" Dokumente in die Suchergebnismenge aufgenommen. Heißt: dateOfIssue <= "heute". Wert 2: Es werden ausschließlich die noch nicht "erschienenen" Dokumente in die Suchergebnismenge aufgenommen: Heißt: dateOfIssue > "heute" |
searchArchiveDocs | Hier sind drei verschiedene Werte möglich:
Wert 0: Das Attribut moveToArchive wird nicht in der Query berücksichtigt. Es werden also archivierte und nicht archivierte Dokumente in das Suchergebnis aufgenommen. Wert 1: Es werden ausschließlich die archivierten Dokumente in die Suchergebnismenge aufgenommen. Heißt: moveToArchive < "heute". Wert 2: Es werden ausschließlich die nicht archivierten Dokumente in die Suchergebnismenge aufgenommen: Heißt: moveToArchive >= "heute" |
additionalQuery | Zusätzliche freie Suchanfrage in Lucene-Syntax, um das Ergebnis weiter einzuschränken.
In diesem String wird das Kürzel @TODAY@ durch die Lucene-Schreibweise für das heutige Datum ersetzt. Außerdem sind einfache Rechenoperationen der Form @TODAY[+-][0-9]*[dmy]?@ möglich. Beispiel: dateOfIssue:[@TODAY-30d@ TO @TODAY@] zeigt Objekte zwischen Heute und Heute - 30 Tagen. Als weitere Grenzwerte können auch der Wert 000000000 für –unendlich und zzzzzzzzz für +unendlich verwendet werden (Beispiel: dateOfIssue:[000000000 TO @TODAY-12m@] zeigt Objekte von minus unendlich bis heute - 12 Monaten an, also alles, was älter als 1 Jahr ist). |
langComparator | Per Default werden nur Dokumente in der aktuellen Sprache zurückgeliefert werden. Im asymmetrischen Mehrsprachigkeitsmodus kann man dieses Verhalten durch diese Property ändern.
Wert 0: Das Sprachkennzeichen des DynDocSearchEnt wird ignoriert. Das Default-Verhalten gilt. Wert 1: Es werden nur Dokumente mit derselben Sprache wie das DynDocSearchEnt selbst (Property languageInd) zurückgeliefert. Wert 2: Es werden nur Dokumente mit einer anderen Sprache als im DynDocSearchEnt angegeben zurückgeliefert. Wert 3: Es werden Dokumente aller Sprachen zurückgeliefert. |
sortProperty | Die Suchergebnisse werden anhand dieser Lucene-Property sortiert. Die Suchanfrage wird entsprechend modifiziert. |
refreshInterval | Die Suchergebnisse werden grundsätzlich gecached, aber nach einer Sekunde automatisch invalidiert (TimedDependencyManager).
Hier kann man diesen Wert durch ein anderes Intervall in Sekunden überschreiben. Außerdem ist es möglich, die Suchergebnisse über die Admin-Seite invalidateTimers gezielt zu invalidieren. |
Programmierung innerhalb von Templates
Innerhalb von Templates kann auf das Suchergebnis noch durch die folgenden ResourceUri-Parameter Einfluss auf das Suchergebnis genommen werden:
ResourceUri-Parameter | Funktion |
TemplatesConstants.PARAM_SCORE (score) | Wenn "true", werden die zurückgelieferten CoreMedia Dokumente in ScoredDocument Objekte gekapselt, damit der jeweilige Lucene-Score (die Treffer-Qualität) vom aufrufenden Template ausgewertet werden kann. |
TemplatesConstants.PARAM_MAX (max) | Überschreibt die Property maxResults. |
TemplatesConstants.PARAM_FOLDERID (folderId) | Überschreibt die Property searchFolders. |
TemplatesConstants.PARAM_ADDITIONAL_QUERY (adq) | Zusätzliche freie Suchanfrage in Lucene-Syntax, um das Ergebnis weiter einzuschränken. |
Erstellung von Suchformularen
Die Erstellung eines Suchformulars entspricht einer Einbindung von Suchanfragen bzw. deren gecachten Ergebnissen in ein Standard GSB Formular. Siehe daher auch das Dokument GSB7/Formularbaukasten.
Prinzip
Die Klasse
de.bundonline.basis.web.struts.action.AbstractQueryAction
implementiert eine Blättern-Funktionalität inkl. des hierfür benötigten Caches der Suchergebnisse.
Um diese Funktionalität zu nutzen ist eine eigene Klasse bereitzustellen, welche von der oben angegebenen Klasse abgeleitet ist. Die ableitende Action muss zwingend die Methode
<syntaxhighlight lang="xml" enclose="div">public boolean storeResultAttributes(Properties propAction,
CoreMediaActionForm form, Document docForm, HttpServletRequest request, int nResultsPerPage, String sResultAttribute)</syntaxhighlight>
implementieren, um
- die Suchergebnisse zu ermitteln und
- diese mit einem Aufruf von QueryResultCache.storeResultAttributes intern speichern.
Das Ergebnis wird dann in der Session für die Blätterfunktionalität gespeichert und beim Blättern über einen Index referenziert. Das HFForm-Template kann anschließend über diverse Hilfsmethoden die einzelnen Blättern-Links generieren und die Ergebnisse der aktuellen Seite anzeigen.
Cache Größe
Damit die Session durch viele Suchanfragen nicht allmählich überläuft, wird nur eine bestimmte Anzahl von Suchanfragen gespeichert. Diese Anzahl kann über das SiteGlobals-ConfigInt QueryResultCacheSize konfiguriert werden. Der Defaultwert ist 5. Die jeweils ältesten Ergebnisse werden aus dem Cache entfernt, wenn die durch den Konfigurationseintrag bestimmt Maximalanzahl überschritten wird.
Kontrolle des Speicherbedarfs
Das Speichern von Suchergebnissen kann u.U. dennoch zuviel Speicherplatz belegen. In diesem Fall empfiehlt es sich, jeden Blättern-Aufruf neu zu generieren.
Hierzu kann man dem Aufruf der storeResultAttributes Methode einen sogenannten QueryPerformer übergeben. Dieser muss lediglich folgende Methode implementieren, welche dann die eigentliche Suche bei jedem Aufruf neu durchführt: public List performQuery();
Hinweis: Sinnvollerweise erhält das verwendete Objekt beim Konstruktor bereits sämtliche benötigten Parameter für die Suche.
Action Properties und Formular Parameter
Alle von der Klasse AbstractQueryAction abgeleiteten Actions verstehen standardmäßig die folgenden Action-Properties:
- resultsPerPage: Anzahl der anzuzeigenden Suchergebnisse/Seite. Ein Wert < 1 bedeutet, dass alle Suchergebnisse angezeigt werden sollen. Das ist auch der Default. Dieser Wert kann durch den gleichnamigen Request-Parameter überschrieben werden.
- resultAttribute: Name des Request-Attributs, in dem das Ergebnis gespeichert werden soll. Der Defaultwert ist HibernateQueryAction.DEFAULT_RESULT_ATTRIBUT bzw. 'queryResult'.
Der Wert sollte nach Möglichkeit nicht geändert werden, da es sonst evtl. Probleme mit dem Caching geben kann.
Außerdem werden folgende Formular-Parameter berücksichtigt:
- resultsPerPage: Anzahl der anzuzeigenden Suchergebnisse/Seite. Ein Wert < 1 bedeutet, dass alle Suchergebnisse angezeigt werden sollen. Dieser Wert überschreibt ggf. die gleichnamige Action-Property.
- queryResultId: Wenn dieser Parameter angegeben ist, werden die übrigen Parameter und Action-Properties nicht mehr ausgewertet, sondern eine vorhandene Suche aus dem Suchergebnis-Cache mit dieser ID verwendet. Lediglich der Parameter pageNo wird berücksichtigt.
- pageNo: 0-basierter Index der anzuzeigenden Seite der Suchergebnisse. Dieser Parameter wird nur berücksichtigt, wenn eine queryResultId angegeben wurde.
Standard Lucene Action
Die von AbstractQueryAction abgeleitete Klasse LuceneQueryAction führt eine Standard-Anfrage über Lucene durch. Sie berücksichtigt zusätzlich die folgenden Action-Properties (vorrangig vor den entsprechenden Request-Parametern!):
- dbName: Name der zu verwendenden Lucene-Datenbank. Der Default ist BundOnlineRetrievalUtil.LUCENE_INDEX_DB_NAME (bolBasis).
- docTypes: Zu berücksichtigende Dokumenttypen (durch Whitespace, Komma oder Semikolon getrennt).
- sortString: Zu verwendende Sortierung. Die hier angegebenen Document-Properties müssen alle zurückgelieferten Dokument besitzen.
- ignoreParams: Namen der bei der Suche zu ignorierenden Request-Parametern (durch Whitespace, Komma oder Semikolon getrennt).
- ignoreOneOfTheseWordsDefault: Wenn der Request-Parameter oneOfTheseWords einen der hier angegebenen Werte hat, wird er ignoriert. Auf diese Weise kann man eine Hilfestellung als Defaultwert eintragen.
- ignoreAllOfTheseWordsDefault: Wenn der Request-Parameter allOfTheseWords einen der hier angegebenen Werte hat, wird er ignoriert. Auf diese Weise kann man eine Hilfestellung als Defaultwert eintragen.
- ignoreSearchEngineQueryStringDefault: Wenn der Request-Parameter searchEngineQueryString einen der hier angegebenen Werte hat, wird er ignoriert. Auf diese Weise kann man eine Hilfestellung für das searchEngineQueryString-Format als Defaultwert eintragen.
- ignoreDateValueDefault: Wenn die Request-Parameter lastChangeAfter oder lastChangeAfter einen der hier angegebenen Werte haben, werden sie ignoriert. Auf diese Weise kann man eine Hilfestellung für das Datums-Format als Defaultwert eintragen.
- parameterMappings: Liste von Parameter-Mappings. Die einzelnen Mappings werden durch Newlines, Komma oder Semikolon getrennt.
Beispiel: <syntaxhighlight lang="xml" enclose="div">
parameterMappings=\ thema=cl2Categories_Themen,\ liste=cl2Categories_Verteilerlisten
</syntaxhighlight>
- modifyParams: Liste von Parameter-Mappings, welche den Parameter-Wert in eine freie additional-Query umwandeln. Das Token @VALUE@ wird durch den aktuellen Wert des Request-Parameters ersetzt. Die einzelnen Mappings werden durch Newlines, Komma oder Semikolon getrennt.
Beispiel (Suche nach Dokumenttiteln mit Worten, die mit dem Parameterwert anfangen) :
<syntaxhighlight lang="xml" enclose="div"> modifyParams=\
param=+title:(@VALUE@)
</syntaxhighlight>
Im Formularfeld eingegebene Worte werden per AND miteinander verknüpft.
Wortgruppen in Anführungszeichen werden als Gruppe behandelt.
Die Wildcards ? und * werden wie erwartet ausgewertet. Sie dürfen nur nicht am Anfang eines Ausdrucks stehen (Lucene-Beschränkung).
Intern werden diese Parameter in standardSearchExpression-Parameter umgewandelt, die innerhalb der Klasse AbstractSearcher ausgewertet werden.
- inhibitSearchParameters: Wenn einer der dort konfigurierten Request-Parameter den angegebenen Wert hat, wird die Suche nicht durchgeführt. Die einzelnen Parameter werden durch Newlines, Komma oder Semikolon getrennt.
Beispiel:
<syntaxhighlight lang="xml" enclose="div"> inhibitSearchParameters=\
oneOfTheseWords=Erweiterte Suche,\ oneOfTheseWords=Expert Search,\ allOfTheseWords=Erweiterte Suche,\ allOfTheseWords=Expert Search,\ searchEngineQueryString=Erweiterte Suche,\ searchEngineQueryString=Expert Search
</syntaxhighlight>
- additionalQuery: Erweiterte Suchanfrage