Für ein Projekt musste ich einen Suchmechanismus implementieren. Die Wahl von Hibernate Search war dabei auf Grund vieler Vorteile für das Projekt klar. Allerdings gab es eine Besonderheit in diesem Projekt, die ich bei der Suche beachten musste und für die ich keine existierende Lösung gefunden habe: Bestimmte Einträge der zu indizierenden Entitäten sind nur dann sichtbar, wenn der Nutzer, der die Suche ausführt, eingelogged ist. Diese Einträge sollten aber auf jeden Fall durchsucht werden können. Nach längerer Recherche habe ich keine existierende Lösung gefunden, die diesem Problem begegnet, daher habe ich einen eigenen Ansatz verfolgt.
Die Entität wird normal mittels der Hibernate Search Annotationen indiziert, für alle Einträge, deren Sichtbarkeit geregelt werden kann, wird jedoch eine eigene FieldBridge benutzt, die als Feldnamen für das Lucene-Document eine Kombination aus Sichtbarkeit und gewünschtem Feldnamen benutzt, so dass die Einträge im Document am Ende so aussehen könnten:
EXTERNAL_name: Mr. X
COMMUNITY_name: Mr. X
EXTERNAL_project: XYZ
COMMUNITY_age: 24
COMMUNITY_phone: 1234567890
Wichtig für meinen Ansatz ist, dass Einträge, die für alle sichtbar sind, zusätzlich auch mit der Sichtbarkeit für eingeloggte Nutzer gespeichert werden (oder falls es noch mehr Levels gibt entsprechend auch für alle alle weiteren “kleineren” Levels).
Die Frage ist nun, wie in einem so strukturierten Dokument gesucht wird. Ich habe dafür leider keine Lösung gefunden, die den existierenden Parser für Suchausdrücke von Lucene benutzten kann. Daher wird zunächst eine eigener Parser benötigt, der z. B. mit javacc implementiert werden kann. Die grundsätzliche Idee ist nun, dass dieser Parser mittels der Lucene API Suchausdrücke auf den im Document gespeicherten Feldern (hier also “name”, “project”, “age” und “phone”) baut und dabei vor jeden Feldnamen das gerade notwendige Sichtbarkeitslevel (“COMMUNITY” oder “EXTERNAL”) schreibt, so dass nur auf den Feldern des entsprechenden Levels gesucht werden kann.