27.5. Abfrage Erzeugungs API

Zusätzlich zum automatischen Analysieren vom Abfragen ist es auch möglich diese durch eine API zu erzeugen.

Benutzerabfragen können mit durch API erstellte Abfragen kombiniert werden. Der Abfrage Parser kann verwendet werden um eine Abfrage von einem String zu erstellen:

<?php
$query = Zend_Search_Lucene_Search_QueryParser::parse($queryString);
        

27.5.1. Abfrageparser Ausnahmen

Der Abfrageparser kann zwei Typen von Ausnahmen erstellen.

  • Zend_Search_Lucene_Exception wird geworfen wenn irgendwas im Abfrageparser selbst falsch läuft.

  • Zend_Search_Lucene_Search_QueryParserException wird geworfen im Fall einer Abfragesyntax Ausnahme.

Deswegen ist es eine gute Idee die Zend_Search_Lucene_Search_QueryParserException zu fangen und entsprechende Nachrichten zu erstellen:

<?php
try {
    $query = Zend_Search_Lucene_Search_QueryParser::parse($queryString);
} catch (Zend_Search_Lucene_Search_QueryParserException $e) {
    echo "Abfrage Syntax Fehler: " . $e->getMessage() . "\n";
}
            

Die selbe Technik kann (und sollte) für die find() Methode des Zend_Search_Lucene Objektes verwendet werden.

27.5.2. Begriffsabfrage

Begriffsabfragen sind für Suchen nach einem einzelnen Begriff gedacht.

Abfragestring:

word1
        

oder

Aufbau der Abfrage mit der Programmierschnittstelle (API):

<?php
$term  = new Zend_Search_Lucene_Index_Term('word1', 'field1');
$query = new Zend_Search_Lucene_Search_Query_Term($term);
$hits  = $index->find($query);
        

Das Term Feld ist optional. Zend_Search_Lucene durchsucht alle Felder wenn das Feld nicht spezifiziert wurde:

<?php
$term  = new Zend_Search_Lucene_Index_Term('wort1');  // Sucht 'word1' durch alle indizierten Felder
$query = new Zend_Search_Lucene_Search_Query_Term($term);
$hits  = $index->find($query);
            

27.5.3. Mehrfache Begriffsabfrage

Mehrfache Begriffsabfragen sind für Suchen mit einem Satz von Begriffen gedacht.

Jeder Begriff dieses Satzes kann als required (notwendig), prohibited (verboten) oder neither (weder noch) definiert werden.

  • required bedeutet, dass Dokumente, die diesen Begriff nicht enthalten, nicht der Abfrage entsprechen;

  • prohibited bedeutet, dass Dokumente, die diesen Begriff enthalten, nicht der Abfrage entsprechen;

  • neither, in welchem Fall Dokumenten den Begriff weder nicht enthalten dürfen, noch den Begriff enthalten müssen. Nichtsdestrotrotz muß ein Dokument mindestens einem Begriff entsprechen, um der Abfrage zu entsprechen.

Beim Hinzufügen optionaler Begriffe zu einer Abfrage mit notwendigen Begriffen wird zwar derselbe Ergebnissatz (wie ohne die optionalen Begriffe) zurückgegeben, die Treffer, welche die optionalen Begriffe enthalten, werden aber weiter oben im Ergebnissatz erscheinen.

Beide Suchmethoden können für Mehrfache Begriffsabfragen verwendet werden.

Abfragestring:

+word1 author:word2 -word3
  • '+' wird für notwendige Begriffe verwendet.

  • '-' wird für verbotene Begriffe verwendet.

  • Der 'field:' Präfix wird für die Angabe des Dokumentenfelds für die Suche verwendet. Wenn er weggelassen wird, wird 'contents' verwendet.

oder

Aufbau der Abfrage mit der Programmierschnittstelle (API):

<?php
$query = new Zend_Search_Lucene_Search_Query_MultiTerm();

$query->addTerm(new Zend_Search_Lucene_Index_Term('word1'), true);
$query->addTerm(new Zend_Search_Lucene_Index_Term('word2'), null);
$query->addTerm(new Zend_Search_Lucene_Index_Term('word3'), false);

$hits  = $index->find($query);
        

Das $signs Array enthält Informationen über den Begriffstyp:

  • true wird für notwendige Begriffe verwendet.

  • false wird für verbotene Begriffe verwendet.

  • null wird für weder notwendige noch verbotene Begriffe verwendet.

27.5.4. Wildcard Abfragen

Wildcard Abfragen sind dazu gedacht um nach einem Set von Ausdrücken zu suchen die einem definierten Pattern entsprechen.

Das '?' Symbol wird als Wildcard für ein einzelnes Zeichen verwendet.

Das '*' Symbol wird als Woldcard für mehrere Zeichen verwendet.

Abfragestring:

test*
field1:test*
            

oder

Abfrageerstellung durch die API:

<?php
$pattern = new Zend_Search_Lucene_Index_Term('test*', 'field1');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$hits  = $index->find($query);
            

Ausdrucksfelder sind optional. Zend_Search_Lucene durchsucht alle Felder wenn das Feld nicht spezifiziert wurde:

<?php
$pattern = new Zend_Search_Lucene_Index_Term('test*');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$hits  = $index->find($query);
            

27.5.5. Phrasenabfrage

Phrasenabfragen sind für Suchen nach einer Phrase gedacht.

Phrasenabfragen sind sehr flexibel und erlauben es, sowohl nach einer exakten Phrase als auch nach ungenauen Phrasen zu suchen.

Phrasen können auch Lücken oder mehrere Begriffe an der selben Stelle enthalten. Diese können mit Hilfe das Analysators für verschiedene Zwecke generiert werden, z.B. kann ein Begriff verdoppelt werden, um das Gewicht des Begriffs zu erhöhen oder verschiedene Synonyme können an einer Stelle platziert werden.

<?php
$query1 = new Zend_Search_Lucene_Search_Query_Phrase();

// Füge 'word1' an der relativen Position 0 hinzu.
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word1'));

// Füge 'word2' an der relativen Position 1 hinzu.
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word2'));

// Füge 'word3' an der relativen Position 3 hinzu.
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word3'), 3);

...

$query2 = new Zend_Search_Lucene_Search_Query_Phrase(
                array('word1', 'word2', 'word3'), array(0,1,3));

...

// Abfrage ohne eine Lücke.
$query3 = new Zend_Search_Lucene_Search_Query_Phrase(
                array('word1', 'word2', 'word3'));

...

$query4 = new Zend_Search_Lucene_Search_Query_Phrase(
                array('word1', 'word2'), array(0,1), 'annotation');
        

Eine Phrasenabfrage kann in einem Schritt mit einem Klassenkonstruktor oder Schritt für Schritt mit der Zend_Search_Lucene_Search_Query_Phrase::addTerm() Methode erstellt werden.

Der Zend_Search_Lucene_Search_Query_Phrase Klassenkonstruktor nimmt drei optionale Argumente entgegen:

<?php
Zend_Search_Lucene_Search_Query_Phrase([array $terms[, array $offsets[, string $field]]]);
        

$terms ist ein Array mit Strings, welche einen Satz von Begriffen für die Phrase enthalten. Wenn dies ausgelassen wird oder null entspricht, wird eine leere Abfrage erstellt.

$offsets ist ein Array mit ganzen Zahlen, welche den Offset der jeweiligen Begriffe der Phrase enthalten. Wenn dies ausgelassen wird oder null entspricht, werden die Positionen der Begriffe als array(0, 1, 2, 3, ...) angenommen.

$field ist ein String, der das zu durchsuchende Dokumentenfeld angibt. Wenn dies ausgelassen wird oder null entspricht, wird das Standardfeld durchsucht. Diese Version von Zend_Search_Lucene verwendet das 'contents' Feld als Standard, aber es ist für weitere Versionen geplant, dieses Verhalten auf "jedes Feld" zu ändern.

<?php
$query = new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'framework'));
        

Demnach wird hier nach der Phrase 'zend framework' gesucht.

<?php
$query = new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'download'), array(0, 2));
        

Es wird nach der Phrase 'zend ????? download' gesucht und die Phrasen 'zend platform download', 'zend studio download', 'zend core download', 'zend framework download' und so weiter werden gefunden.

<?php
$query = new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'framework'), null, 'title');
        

Es wird nach der Phrase 'zend framework' im 'title' Feld gesucht.

Die Zend_Search_Lucene_Search_Query_Phrase::addTerm() Methode nimmt zwei Argumente entgeben. Ein Zend_Search_Lucene_Index_Term Objekt ist erforderlich und die Position optional:

<?php
Zend_Search_Lucene_Search_Query_Phrase::addTerm(Zend_Search_Lucene_Index_Term $term[, integer $position]);
        

$term enthält den nächsten Begriff in der Phrase. Er muss das selbe Feld ansprechen wie der vorherige Begriff. Andernfalls wird eine Ausnahme geworfen.

$position gibt die Position des Begriffes an.

<?php
$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend'));
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework'));
        

Demnach wird hier nach der Phrase 'zend framework' gesucht.

<?php
$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend'), 0);
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework'), 2);
        

Es wird nach der Phrase 'zend ????? download' gesucht und die Phrasen 'zend platform download', 'zend studio download', 'zend core download', 'zend framework download' und so weiter werden gefunden.

<?php
$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend', 'title'));
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework', 'title'));
        

Es wird nach der Phrase 'zend framework' im 'title' Feld gesucht.

Der Ungenauigkeitsfaktor (slop factor) legt die Anzahl der anderen erlaubten Begriffe zwischen Begriffen der Phrasenabfrage fest. Wenn die Anzahl 0 ist, entspricht dies der Suche nach einer exakten Phrase. Für größere Werte verhält es sich wie ein WITHIN (innerhalb) oder NEAR (nahe) Operator.

Die Ungenauigkeit ist tatsächlich eine veränderbare Distanz, bei der die Einheiten den Schritten entsprechen, die sich ein Begriff in der Phrasenabfrage von seiner eigentlichen Position entfernen darf. Um zum Beispiel die Reihenfolge zweier Worte zu vertauschen, werden zwei Schritte benötigt (der erste Schritt platziert die Worte übereinander). Um also für Phrasen eine Neuanordnun zu erlauben, muss die Ungenauigkeit mindestens zwei entsprechen.

Exaktere Treffer werden höher bewertet als ungenauere Treffer, so dass die Suchergebnisse nach der Genauigkeit sortiert werden. Die Ungenauigkeit liegt standardmäßig bei 0, was exakte Treffer erfordert.

Der Ungenauigkeitsfaktor kannnach der Erstellung der Abfrage zugeordnet werden:

<?php
// Query without a gap.
$query = new Zend_Search_Lucene_Search_Query_Phrase(array('word1', 'word2'));

// Search for 'word1 word2', 'word1 ... word2'
$query->setSlop(1);
$hits1 = $index->find($query);

// Search for 'word1 word2', 'word1 ... word2',
// 'word1 ... ... word2', 'word2 word1'
$query->setSlop(2);
$hits2 = $index->find($query);
        

27.5.6. Bereichsabfragen

Bereichsabfragen sind dazu gedacht Terme innerhalb eines spezifizierten Intervalls zu suchen.

Abfragestring:

mod_date:[20020101 TO 20030101]
title:{Aida TO Carmen}

oder

Abfrageerstellung durch die API:

<?php
$from = new Zend_Search_Lucene_Index_Term('20020101', 'mod_date');
$to   = new Zend_Search_Lucene_Index_Term('20030101', 'mod_date');
$query = new Zend_Search_Lucene_Search_Query_Range($from, $to, true /* inclusive */);
$hits  = $index->find($query);
            

Begriffsfelder sind optional. Zend_Search_Lucene durchsucht alle Felder wenn das Feld nicht spezifiziert wurde:

<?php
$from = new Zend_Search_Lucene_Index_Term('Aida');
$to   = new Zend_Search_Lucene_Index_Term('Carmen');
$query = new Zend_Search_Lucene_Search_Query_Range($from, $to, falce /* non-inclusive */);
$hits  = $index->find($query);
            

Jede (aber nicht beide) der Begrenzungsausdrücke können auf null gesetzt werden. Zend_Search_Lucene sucht vom Anfang oder bis zum Ende des Verzeichnisses für die spezifizierten Feld(er) für diesen Fall:

<?php
$from = new Zend_Search_Lucene_Index_Term('20020101', 'mod_date');
$query = new Zend_Search_Lucene_Search_Query_Range($from, null, true /* inclusive */);  // sucht nach ['20020101' TO ...]
$hits  = $index->find($query);