Abfragesprache

Java Lucene und Zend_Search_Lucene bieten sehr mächtige Abfragesprachen.

Diese Sprachen sind großteils die selben mit ein paar kleineren Unterschieden welche anbei erklärt werden.

Die komplette Java Lucene Syntax Dokumentation der Abfragesprache kann hier gefunden werden.

Ausdrücke

Eine Abfrage wird in Ausdrücke und Operatoren zerteilt. Es gibt drei Arten von Ausdrücken: Einzelne Ausdrücke, Phrasen und Unterabfragen.

Ein einzelner Ausdruck ist ein einzelnes Wort wie "Test" oder "Hallo".

Eine Phrase ist eine Gruppe von Wörtern die von doppelten Hochkommata umgeben sind wie "Hallo Dolly".

Eine Unterabfrage ist eine Abfrage die von Klammern umgeben ist wie "(Hallo Dolly)".

Mehrere Ausdrücke können mithilfe eines boolschen Operators miteinander kombiniert werden um komplexere Abfragen zu formen (siehe anbei).

Felder

Lucene unterstützt Felder von Daten. Wenn eine Suche durchgeführt wird kann man entweder ein Feld spezifizieren, oder ein Standardfeld verwenden. Der Name des Feldes hängt von den indizierten Daten ab und das Standardfeld wird durch aktuelle Einstellungen definiert.

Der erste und größte Unterschied zu Java Lucene ist der das Ausdrücke standardmäßig über alle Felder gesucht werden.

Es gibt zwei statische Methoden in der Zend_Search_Lucene Klasse welche dem Entwickler das Konfigurieren dieser Einstellungen erlauben:

$defaultSearchField = Zend_Search_Lucene::getDefaultSearchField();
...
Zend_Search_Lucene::setDefaultSearchField('contents');

Der NULL Wert bedeutet, das die Suche über alle Felder durchgeführt wird. Das ist die Standardeinstellung.

Es können spezielle Felder gesucht werden indem der Feldname gefolgt von einem Doppelpunkt ":" angegeben wird, gefolgt von dem Begriff nach dem gesucht wird.

Als Beispiel nehmen wir an das ein Lucene Index zwei Felder enthält - title und text - text ist das Standardfeld. Wenn man das "Der richtige Weg" benannte Dokument finden will welches den Text "gehe nicht diesen Weg" enthält, geht das mit:

title:"Der richtige Weg" AND text:go

oder

title:"Mach es richtig" AND go

Weil "text" das Standardfeld ist, wird der Feld Indikator nicht benötigt.

Beachte: Das Feld nur nur für den Ausdruck, die Phrase oder die Unterabfrage gültig die direkt danach folgt, sodas die Abfrage

title:Mach es richtig

nur "Mach" im title Feld finden wird. Es findet "es" und "richtig" im Standardfeld (wenn das Standardfeld gesetzt ist) oder in allen indizierten Felder (wenn das Standardfeld auf NULL gesetzt ist).

Wildcards

Lucene unterstützt Einzelzeichen und Mehrfachzeichen Suchen mit Wildcards in einzelnen Ausdrücken (aber nicht innerhalb von Phrasenabfragen).

Um eine Einzelzeichen Wildcardsuche durchzuführen kann das "?" Zeichen verwendet werden.

Um eine Mehrzeichen Wildcardsuche durchzuführen kann das "*" Zeichen verwendet werden.

Die Einzelzeichen Wildcardsuche schucht nach Strings die dem Begriff entsprechen wobei das "?" durch ein beliebiges einzelnes Zeichen ersetzt wird. Um, zum Beispiel, nach "Text" oder "Test" zu suchen kann die folgende Suche verwendet werden:

Te?t

Mehrzeichen Wildcardsuche sucht nach 0 oder mehr Zeichen wenn Strings nach passenden Begriffen sucht. Um, zum Beispiel, nach Test, Tests oder Tester zu suchen, kann die folgende Suche verwendet werden:

Test*

Es können "?", "*" oder beide an jeder Stelle des Ausdrucks verwendet werden:

*schrei?t*

Sucht nach "schreibt", "schreibtisch", "beschreibt", "schreist" und so weiter.

Beginnend mit ZF 1.7.7 benötigen Wildcard Präfixe einen nicht-Wildcard Präfix. Die standardmäßige Länge des Präfixes ist 3 (wie in Java Lucene). Die Ausdrücke "*", "te?t", "*wr?t*" werden also eine Exception werfen [15].

Das kann durch Verwendung der Methoden Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() und Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength() geändert werden.

Ausdrücke verändern

Lucene unterstützt die Veränderung von Abfrageausdrücken und bietet damit ein beites Spektrum von Suchoptionen.

Der "~" Modifikator kann für verwendet werden um eine annähernde Suche auf Phrasen oder Fuzzy Suchen für individuelle Ausdrücke durchzuführen.

Bereichs Suchen

Bereichsabfragen erlauben es Entwicklern passende Dokumente zu finden deren Werte der Felder zwischen der unteren und oberen Grenze sind die durch die Bereichsabfrage spezifiziert wurden. Bereichsabfragen können inklusive oder exklusive der oberen und unteren Grenze sein. Sortierungen werden lexikalisch durchgeführt.

mod_date:[20020101 TO 20030101]

Das wird Dokumente finden dessen lod_date Felder Werte zwischen 20020101 und 20030101 inklusive haben. Es ist zu beachten das Bereichsabfragen nicht für Datumsfelder reserviert sind. Bereichsabfragen können auch mit nicht-datums Felder verwendet werden:

title:{Aida TO Carmen}

Das wird alle Dokumente finden dessen Titel zwischen Aida und Carmen sortiert sind, aber ohne Aida und Carmen.

Bereichsabfragen inklusive, werden durch eine eckige Klammer abgegrenzt. Bereichsabfragen exklusive werden durch geschlungene Klammern abgegrenzt.

Wenn kein Feld spezifiziert wurde sucht Zend_Search_Lucene standardmäßig nach spezifizierten Intervallen in allen Feldern.

{Aida TO Carmen}

Fuzzy Suchen

Zend_Search_Lucene unterstützt, genauso wie Java Lucene, die Fuzzy Suche basierend auf der Levenshtein Distanz oder dem Edit Algorithmus. Um eine Fuzzy Suche durchzuführen muß das Tilde Symbol "~", am Ende eines einzelnen Wortbegriffs verwendet werden. Um zum Beispiel nach einem Begriff zu suchen der in der Aussprache ähnlich zu "Raum" ist kann die folgende Fuzzy Suche verwendet werden:

roam~

Diese Suche wird Begriffe wie "Baum" und "Saum" finden. Zusätzliche (optionale) Parameter können die benötigte Ähnlichkeit spezifizieren. Der Wert muß zwischen 0 und 1 sein. Mit einem Wert näher bei 1 werden nur Begriffe mit einer höheren Warscheinlichkeit gefunden. Zum Beispiel:

roam~0.8

Der verwendete Standardwert wenn der Parameter nicht angegeben wurde ist 0.5.

Einschränkung passender Ausdrücke

Wildcard, Bereichs- und Fuzzy Suchabfragen können bei zu vielen Ausdrücken passen. Das kann die Geschwindigkeit der Suche sehr stark verlangsamen.

Deshalb setzt Zend_Search_Lucene ein Limit der passenden Ausdrücke pro Abfrage (Unterabfrage). Dieses Limit kann durch Verwendung der Methoden Zend_Search_Lucene::getTermsPerQueryLimit() und Zend_Search_Lucene::setTermsPerQueryLimit($limit) empfangen und gesetzt werden.

Das standardmäßige Limit für passende Ausdrücke ist 1024.

Angenäherte Suchen

Lucene unterstützt das Finden von Wörtern aus einer Phrase die einen spezifizierten Abstand an Wörtern in einem String weg sind. Um eine angenäherte Suche durchzuführen muß das Tilde, "~", Symbol am Ende der Phrase verwendet werden. Um zum Beispiel nach "Zend" und "Framework" innerhalb von 10 Wörtern zueinander in einem Dokument zu suchen kann die folgende Suche verwendet werden:

"Zend Framework"~10

Einen Ausdruck schneller machen

Java Lucene und Zend_Search_Lucene bieten einen Level der Relevanz von passenden Dokumenten basierend auf den gefundenen Ausdrücken. Um die Relevanz eines Ausdrucks zu erhöhen kann das Karet, "^", Symbol mit einem Boost Faktor (einer Zahl) am Ende des Ausdrucks nach dem gesucht wird, verwendet werden. Je höher Boost Faktor ist, desdo relevanter wird der Ausdruck werden.

Das boosten erlaubt die Kontrolle der Relevanz eines Dokuments durch das boosten individueller Ausdrücke. Wenn man zum Beispiel nach

PHP framework

sucht und will das der Ausdruck "PHP" mehr Relevanz hat, kann er durch Verwendung des ^ Symbols zusammen mit einem Boost Faktor beim Ausdruck geboostet werden. Man würde zum Beispiel folgendes angeben:

PHP^4 framework

Das macht Dokumente in denen der Ausdruck PHP vorkommt relevanter. Man kann genauso Phrasenausdrücke boosten und Unterabfragen wie im Beispiel gezeigt:

"PHP framework"^4 "Zend Framework"

Standardwert ist der Boost Faktor 1. Auch wenn der Boost Faktor positiv sein muß, kann er kleiner als 1 sein (z.B. 0.2).

Boolsche Operatoren

Boolsche Operatoren erlauben es Ausdrücke durch logische Operatoren zu kombinieren. Lucene unterstützt AND, "+", OR, NOT und "-" als boolsche Operatoren. In Java Lucene müssen alle boolschen Operatoren GROßGESCHRIEBEN werden. In Zend_Search_Lucene nicht.

AND, OR, und NOT Operatoren und "+", "-" definieren zwei unterschiedliche Stile um boolsche Abfragen zu erstellen. Im Gegensatz zu Java Lucene erlaubt es Zend_Search_Lucene nicht diese zwei Stile zu mischen.

Wenn der AND/OR/NOT Stil verwendet wird dann muß der AND oder OR Operator zwischen allen Abfrageausdrücken vorhanden sein. Jedem Ausdruck kann auch ein NOT Operator vorangestellt werden. Der AND Operator hat eine höhere Präzedenz als der OR Operator. Das unterscheidet sich vom Verhalten von Java Lucene.

AND

Der AND Operator bedeutet das alle Ausdrücke der "AND Gruppe" in einigen Teilen der gesuchten Feld(er) passen müssen.

Um nach Dokumenten zu Suchen die "PHP Framework" und "Zend Framework" enthalten kann die folgende Abfrage verwendet werden:

"PHP Framework" AND "Zend Framework"

OR

Der OR Operator teilt die Abfrage in verschiedene optionale Begriffe.

Um nach Dokumenten zu Suchen die "PHP Framework" oder "Zend Framework" enthalten kann die folgende Abfrage verwendet werden:

"PHP Framework" OR "Zend Framework"

NOT

Der NOT Operator scheidet Dokumente aus die den Ausdruck nach NOT enthalten. Aber eine "AND Gruppe" die nur Ausdrücke mit NOT Operatoren enthält, gibt ein leeres Ergebnis zurück statt einem kompletten Set von indizierten Dokumenten.

Um nach Dokumenten zu Suchen die "PHP Framework" enthalten aber "Zend Framework" nicht kann die folgende Abfrage verwendet werden:

"PHP Framework" AND NOT "Zend Framework"

&&, ||, und ! Operatoren

&&, ||, und ! können statt den AND, OR und NOT Notation verwendet werden.

+

Der "+" oder benötigende Operator erfordert das der Ausdruck nach dem "+" Symbol im passenden Dokument vorhanden ist.

Um nach Dokumenten zu Suchen die "Zend" enthalten müssen und "Framework" enthalten können, kann die folgende Abfrage verwendet werden:

+Zend Framework

-

Der "-" oder ausschließende Operator schließt Dokumente aus die dem Ausdruck nach dem "-" Symbol entsprechen.

Um nach Dokumenten zu Suchen die "PHP Framework" enthalten aber "Zend Framework" nicht, kann die folgende Abfrage verwendet werden:

"PHP Framework" -"Zend Framework"

kein Operator

Wenn kein Operator verwendet wird, dann wird das Suchverhalten durch den "standardmäßigen boolschen Operator" bestimmt.

Dieser ist standardmäßig auf 'OR' gesetzt.

Das impliziert das jeder Ausdruck standardmäßig optional ist. Er kann oder kann nicht innerhalb des Dokuments enthalten sein, aber Dokumenten mit diesem Ausdruck haben einen Höheren Stellenwert.

Um nach Dokumenten zu Suchen die "PHP Framework" benötigen und "Zend Framework" enthalten können kann die folgende Abfrage verwendet werden:

+"PHP Framework" "Zend Framework"

Der standardmäßige boolsche Operator kann mit den Zend_Search_Lucene_Search_QueryParser::setDefaultOperator($operator) und Zend_Search_Lucene_Search_QueryParser::getDefaultOperator() Methoden gesetzt oder geholt werden.

Diese Methoden arbeiten mit den Zend_Search_Lucene_Search_QueryParser::B_AND und Zend_Search_Lucene_Search_QueryParser::B_OR Konstanten.

Gruppieren

Java Lucene und Zend_Search_Lucene unterstützen die Verwendung von Klammern um Fälle zu gruppieren und Unterabfragen zu erstellen. Das kann nützlich sein wenn man die boolsche Operatoren für eine Abfrage kontrollieren will, oder unterschiedliche Abfragestile mischen will:

+(Framework OR Bibliothek) +php

Zend_Search_Lucene unterstützt Unterabfragen von beliebigen Ebenen.

Felder gruppieren

Lucene unterstützt auch die Verwendung von Klammern um mehrere Fälle in ein einzelnes Feld zu gruppieren.

Um nach einem Titel zu suchen die sowohl das Wort "Rückkehr" und die Phrase "rosaroter Panther" kann die folgende Abfrage verwendet werden:

title:(+Rückkehr +"rosaroter Panther")

Escapen von speziellen Zeichen

Lucene unterstützt das Escapen von speziellen Zeichen die in der Abfragesyntax verwendet werden. Die aktuelle Liste der speziellen Zeichen ist:

+ - && || ! ( ) { } [ ] ^ " ~ * ? : \

+ und - in einem einzelnen Ausdruck werden automatisch als normale Zeichen behandelt.

Für andere Instanzen von solchen Zeichen kann das \ vor jedem speziellen Zeichen verwendet werden der escaped werden soll. Um zum Beispiel nach (1+1):2 zu suchen kann die folgende Abfrage verwendet werden:

\(1\+1\)\:2


[15] Es ist zu beachten das es nicht zu einer Zend_Search_Lucene_Search_QueryParserException kommt, sondern zu einer Zend_Search_Lucene_Exception. Sie wird während dem Umschreiben der Abfrage geworfen.