| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.search.lucene.searching">
- <title>Einen Index durchsuchen</title>
- <sect2 id="zend.search.lucene.searching.query_building">
- <title>Abfrage erstellen</title>
- <para>
- Es gibt zwei Arten, den Index zu durchsuchen. Die erste Methode verwendet den
- Query Parser, um eine Abfrage aus einem String zu erstellen. Die zweite kann
- programmtechnisch eigene Abfragen über die <classname>Zend_Search_Lucene</classname>
- <acronym>API</acronym> erstellen.
- </para>
- <para>
- Vor der Verwendung des bereitgestellten Query Parsers, beachte bitte folgendes:
- <orderedlist>
- <listitem>
- <para>
- Wenn du deine Abfragestrings programmseitig erstellst und dann durch den
- Query Parser verarbeiten lässt, solltest du darüber nachdenken, deine
- Abfragen direkt mit der <acronym>API</acronym> für Abfragen zu erstellen.
- In anderen Worten, der Query Parser wurde für von Menschen eingegebene Texte
- und nicht für von Programmen erstellte Texte entwickelt.
- </para>
- </listitem>
- <listitem>
- <para>
- Nicht in einzelne Tokens aufgeteilte Felder werden am besten direkt zu der
- Abfrage und nicht über den Query Parser hinzugefügt. Wenn die Feldwerte
- durch die Anwendung programmseitig erstellt werden, dann sollte dies für
- Abfrageklauseln dieses Felds ebenfalls geschehen. Ein Analysator, welche der
- Query Parser verwendet, wurde entwickelt, um von Menschen eingegebenen Text
- in Begriffe zu konvertieren. Durch Programme erstellte Werte wie
- Datumsangaben, Schlüsselwörter, usw. sollten mit der Abfrage
- <acronym>API</acronym> erstellt werden.
- </para>
- </listitem>
- <listitem>
- <para>
- In einem Abfrageformular sollten generelle Textfelder den Query Parser
- verwenden. Alle anderen, wie z.B. Datumsbereiche, Schlüsselwörter, usw.
- werden besser direkt durch die <acronym>API</acronym> der Abfrage
- hinzugefügt. Ein Feld mit einem begrenzten Wertebereich, das durch ein
- Pulldown-Menü spezifiziert wird, sollte nicht einem Abfragestring
- hinzugefügt werden, der anschließend wieder geparst wird, sondern eher als
- eine TermQuery Klausel hinzugefügt werden.
- </para>
- </listitem>
- <listitem>
- <para>
- Boolesche Abfragen erlauben es dem Programmierer zwei oder mehr Abfragen
- logisch in eine neue zu kombinieren. Deshalb ist dies der beste Weg, um
- zusätzliche Kriterien zu einer Benutzersuche hinzuzufügen, die durch den
- Abfragestring definiert wird.
- </para>
- </listitem>
- </orderedlist>
- </para>
- <para>
- Beide Arten verwenden die selbe Methode der <acronym>API</acronym>, um den Index
- zu durchsuchen:
- </para>
- <programlisting language="php"><![CDATA[
- $index = Zend_Search_Lucene::open('/data/my_index');
- $index->find($query);
- ]]></programlisting>
- <para>
- Die <methodname>Zend_Search_Lucene::find()</methodname> Methode ermittelt den Eingabetyp
- automatisch und verwendet den Query Parser, um ein entsprechendes
- <classname>Zend_Search_Lucene_Search_Query</classname> Objekt aus einer Eingabe vom Typ
- String zu erstellen.
- </para>
- <para>
- Es ist wichtig zu beachten, dass der Query Parser den Standard Analyzer verwendet, um
- verschiedene Teile des Abfragestrings in Token aufzuteilen. Dadurch werden alle
- Umwandlungen, die auf einen indizierten Text ausgeführt werden, auch für den
- Abfragestring ausgeführt.
- </para>
- <para>
- Der Standardanalysator kann den Abfragestring, für die Unabhängigkeit von Groß- und
- Kleinschreibung, in Kleinbuchstaben umwandeln, Stopwörter entfernen, und andere
- Umwandlungen durchführen.
- </para>
- <para>
- Die <acronym>API</acronym> Methoden transformieren oder filtern Eingabebegriffe in
- keinem Fall. Das passt deshalb eher für computergenerierte oder nicht geteilte Felder.
- </para>
- <sect3 id="zend.search.lucene.searching.query_building.parsing">
- <title>Parsen der Abfrage</title>
- <para>
- Die <methodname>Zend_Search_Lucene_Search_QueryParser::parse()</methodname> Methode
- kann verwendet werden um einen Abfrage String in ein Abfrage Objekt zu parsen.
- </para>
- <para>
- Dieses Abfrageobjekt kann in Abfrage erzeugenden <acronym>API</acronym> Methoden
- verwendet werden um von Benutzern eingegebene Abfragen mit programmtechnisch
- erzeugten Abfragen zu kombinieren.
- </para>
- <para>
- Aktuell ist das in einigen Fällen der einzige Weg um nach einem Wert innerhalb eines
- Feldes ohne Token zu suchen:
- </para>
- <programlisting language="php"><![CDATA[
- $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
- $pathTerm = new Zend_Search_Lucene_Index_Term(
- '/data/doc_dir/' . $filename, 'path'
- );
- $pathQuery = new Zend_Search_Lucene_Search_Query_Term($pathTerm);
- $query = new Zend_Search_Lucene_Search_Query_Boolean();
- $query->addSubquery($userQuery, true /* required */);
- $query->addSubquery($pathQuery, true /* required */);
- $hits = $index->find($query);
- ]]></programlisting>
- <para>
- Die <methodname>Zend_Search_Lucene_Search_QueryParser::parse()</methodname> Methode
- nimmt auch einen optionalen Encoding Parameter, welche die Codierung des Abfrage
- Strings definieren kann:
- </para>
- <programlisting language="php"><![CDATA[
- $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr,
- 'iso-8859-5');
- ]]></programlisting>
- <para>
- Wenn der Codierungs Parameter unterdrückt wurde, wird das aktuelle Gebietsschema
- verwendet.
- </para>
- <para>
- Es ist auch möglich eine Standard Codierung für den Abfragestring mit der
- <methodname>Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding()</methodname>
- Methode zu definieren:
- </para>
- <programlisting language="php"><![CDATA[
- Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('iso-8859-5');
- ...
- $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
- ]]></programlisting>
- <para>
- <methodname>Zend_Search_Lucene_Search_QueryParser::getDefaultEncoding()</methodname>
- gibt die aktuelle Standard Codierung des Abfrage Strings zurück (leerer String
- bedeutet "aktuelles Gebietsschema").
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.search.lucene.searching.results">
- <title>Suchergebnisse</title>
- <para>
- Das Suchergebnis ist ein Array mit
- <classname>Zend_Search_Lucene_Search_QueryHit</classname> Objekten. Jedes davon hat zwei
- Eigenschaften: <code>$hit->id</code> ist eine Dokumentnummer innerhalb des Index
- und <code>$hit->score</code> ist ein Punktwert für den Treffer im Suchergebnis. Das
- Ergebnis wird anhand der Punktwerte sortiert (absteigend von der besten Wertung).
- </para>
- <para>
- Das <classname>Zend_Search_Lucene_Search_QueryHit</classname> Objekt beinhaltet zudem
- jedes Feld des <classname>Zend_Search_Lucene_Document</classname>, das bei der Suche
- gefunden wurde, als Eigenschaft des Treffers. Im folgenden Beispiel, wird ein Treffer
- mit zwei Feldern des entsprechenden Dokuments zurückgegeben: Titel und Autor.
- </para>
- <programlisting language="php"><![CDATA[
- $index = Zend_Search_Lucene::open('/data/my_index');
- $hits = $index->find($query);
- foreach ($hits as $hit) {
- echo $hit->score;
- echo $hit->title;
- echo $hit->author;
- }
- ]]></programlisting>
- <para>
- Gespeicherte Felder werden immer in UTF-8 Kodierung zurückgegeben.
- </para>
- <para>
- Optional kann das originale <classname>Zend_Search_Lucene_Document</classname> Objekt
- vom <classname>Zend_Search_Lucene_Search_QueryHit</classname> Objekt zurückgegeben
- werden. Du kannst gespeicherte Teile des Dokuments durch Verwendung der
- <methodname>getDocument()</methodname> Methode des Indexobjektes zurückerhalten und
- diese dann durch die <methodname>getFieldValue()</methodname> Methode abfragen:
- </para>
- <programlisting language="php"><![CDATA[
- $index = Zend_Search_Lucene::open('/data/my_index');
- $hits = $index->find($query);
- foreach ($hits as $hit) {
- // Gibt Zend_Search_Lucene_Document Objekte für diesen Treffer zurück
- echo $document = $hit->getDocument();
- // Gibt ein Zend_Search_Lucene_Field Objekt von
- // Zend_Search_Lucene_Document zurück
- echo $document->getField('title');
- // Gibt den String Wert des Zend_Search_Lucene_Field Objektes zurück
- echo $document->getFieldValue('title');
- // Gleich wie getFieldValue()
- echo $document->title;
- }
- ]]></programlisting>
- <para>
- Die Felder, die in einem <classname>Zend_Search_Lucene_Document</classname> Objekt
- verfügbar sind, werden beim Indizieren festgelegt. Die Dokumentenfelder werden durch die
- Indizieranwendung (z.B. LuceneIndexCreation.jar) im Dokument entweder nur indiziert oder
- indiziert und gespeichert.
- </para>
- <para>
- Beachte, dass die Dokumentidentität ('path' in unserem Beispiel) auch im Index
- gespeichert wird und von ihm zurückgewonnen werden muß.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.results-limiting">
- <title>Begrenzen des Ergebnissets</title>
- <para>
- Der berechnungsintensivste Teil des Suchens ist die Berechnung der Treffer. Das kann für
- große Ergebnisse einige Sekunden dauern (Zehntausende von Treffern)
- </para>
- <para>
- <classname>Zend_Search_Lucene</classname> bietet die Möglichkeit die Ergebnisse mit den
- <methodname>getResultSetLimit()</methodname> und
- <methodname>setResultSetLimit()</methodname> Methoden zu begrenzen:
- </para>
- <programlisting language="php"><![CDATA[
- $currentResultSetLimit = Zend_Search_Lucene::getResultSetLimit();
- Zend_Search_Lucene::setResultSetLimit($newLimit);
- ]]></programlisting>
- <para>
- Der Standardwert von 0 bedeutet 'keine Grenze'.
- </para>
- <para>
- Es gibt nicht die 'besten N' Ergebnisse, sonder nur die 'ersten N'
- <footnote>
- <para>
- Zurückgegebenen Ergebnisse werden trotzdem nach dem Treffer geordnet oder
- anhand der spezifizierten Reihenfolge, wenn diese angegeben wurde.
- </para>
- </footnote>.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.results-scoring">
- <title>Ergebnisgewichtung</title>
- <para>
- <classname>Zend_Search_Lucene</classname> verwendet die selben Gewichtungsalgorithmen
- wie Java Lucene. Alle Treffer in den Suchergebnisse werden standardmäßig nach einem
- Punktwert sortiert. Treffer mit höherem Punktwert kommen zuerst, und Dokumente mit
- höherem Punktwert passen präziser auf die Abfrage als solche mit niedrigerem Punktwert.
- </para>
- <para>
- Grob gesagt, haben die Suchergebnisse einen höheren Punktwert, welche den gesuchten
- Begriff oder die gesuchte Phrase häufiger enthalten.
- </para>
- <para>
- Der Punktwert kann über die <code>score</code> Eigenschaft des Treffers ermittelt
- werden:
- </para>
- <programlisting language="php"><![CDATA[
- $hits = $index->find($query);
- foreach ($hits as $hit) {
- echo $hit->id;
- echo $hit->score;
- }
- ]]></programlisting>
- <para>
- Die <classname>Zend_Search_Lucene_Search_Similarity</classname> Klasse wird verwendet,
- um den Punktwert für jeden Treffer zu berechnen. Beachte den <link
- linkend="zend.search.lucene.extending.scoring">Erweiterbarkeit. Algorithmen für
- Punktwertermittlung</link> Abschnitt für weitere Details.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.sorting">
- <title>Sortierung der Suchergebnisse</title>
- <para>
- Standardmäßig werden die Suchergebnisse nach dem Punktwert sortiert. Der Programmierer
- kann dieses Verhalten durch das Setzen eines Sortierfeldes und der Parameter für die
- Sortierreihenfolge geändert werden.
- </para>
- <para>
- <code>$index->find()</code> Aufruf kann verschiedene optionale Parameter entgegen
- nehmen:
- </para>
- <programlisting language="php"><![CDATA[
- $index->find($query [, $sortField [, $sortType [, $sortOrder]]]
- [, $sortField2 [, $sortType [, $sortOrder]]]
- ...);
- ]]></programlisting>
- <para>
- Ein Name von gespeicherten Feldern nach denen Ergebnisse sortiert werden sollen sollte
- als <varname>$sortField</varname> Parameter übergeben werden.
- </para>
- <para>
- <varname>$sortType</varname> kann ausgelassen werden oder die nachfolgenden Werte
- annehmen: <constant>SORT_REGULAR</constant> (vergleiche Items normal - Standardwert),
- <constant>SORT_NUMERIC</constant> (vergleiche Items numerisch),
- <constant>SORT_STRING</constant> (vergleiche items als Strings).
- </para>
- <para>
- <varname>$sortOrder</varname> kann ausgelassen werden oder die nachfolgenden Werte
- annehmen: <constant>SORT_ASC</constant> (sortiere in aufsteigender Folge -
- Standardwert), <constant>SORT_DESC</constant> (sortiere in absteigender Folge).
- </para>
- <para>
- Beispiele:
- </para>
- <programlisting language="php"><![CDATA[
- $index->find($query, 'quantity', SORT_NUMERIC, SORT_DESC);
- ]]></programlisting>
- <programlisting language="php"><![CDATA[
- $index->find($query, 'fname', SORT_STRING, 'lname', SORT_STRING);
- ]]></programlisting>
- <programlisting language="php"><![CDATA[
- $index->find($query, 'name', SORT_STRING, 'quantity', SORT_NUMERIC, SORT_DESC);
- ]]></programlisting>
- <para>
- Beim Verwenden von nicht standardmäßigen Sortierreihenfolgen sollte man vorsichtig sein;
- die Abfrage muß Dokumente komplett vom Index empfangen werden, was die Geschwindigkeit
- der Suche dramatisch reduziert.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.highlighting">
- <title>Such Resultate hervorheben</title>
- <para>
- <classname>Zend_Search_Lucene</classname> bietet zwei Optionen für das Highlightinh von
- Suchergebnissen.
- </para>
- <para>
- Die erste ist die Verwendung der <code>Zend_Search_Lucene_Document_Html</code> Klasse
- (siehe <link linkend="zend.search.lucene.index-creation.html-documents">das Kapitel
- über HTML Dokumente</link> für Details) mit den folgenden Methoden:
- </para>
- <programlisting language="php"><![CDATA[
- /**
- * Highlight text with specified color
- *
- * @param string|array $words
- * @param string $colour
- * @return string
- */
- public function highlight($words, $colour = '#66ffff');
- ]]></programlisting>
- <programlisting language="php"><![CDATA[
- /**
- * Highlight text using specified View helper or callback function.
- *
- * @param string|array $words Words to highlight. Words could be organized
- using the array or string.
- * @param callback $callback Callback method, used to transform
- (highlighting) text.
- * @param array $params Array of additionall callback parameters passed
- through into it (first non-optional parameter
- is an HTML fragment for highlighting)
- * @return string
- * @throws Zend_Search_Lucene_Exception
- */
- public function highlightExtended($words, $callback, $params = array())
- ]]></programlisting>
- <para>
- Um das Verhalten beim Highlighting zu verändern kann die
- <methodname>highlightExtended()</methodname> Methode mit einem spezifizierten Callback
- verwendet werden, welche einen oder mehreren Parametern entgegennimmt
- <footnote>
- <para>
- Der erste ist ein <acronym>HTML</acronym> Fragment für das Highlighting und die
- anderen sind abhängig vom Verhalten des Callbacks. Der Rückgabewert ist ein
- highlighted <acronym>HTML</acronym> Fragment.
- </para>
- </footnote>
- , oder durch Erweiterung der <code>Zend_Search_Lucene_Document_Html</code> Klasse und
- dem Anpassen der <methodname>applyColour($stringToHighlight, $colour)</methodname>
- Methode die als Standardmäßiger Callback für das Highlighten verwendet wird.
- <footnote>
- <para>
- In beiden Fällen wird das zurückgegebene <acronym>HTML</acronym> automatisch in
- gültiges <acronym>XHTML</acronym> transformiert.
- </para>
- </footnote>
- </para>
- <para>
- <link linkend="zend.view.helpers">View Helfer</link> können auch als Callbacks im
- Kontext von View Skripten verwendet werden:
- </para>
- <programlisting language="php"><![CDATA[
- $doc->highlightExtended('word1 word2 word3...', array($this, 'myViewHelper'));
- ]]></programlisting>
- <para>
- Das Ergebnis der Highlighting Operation wird von der
- <code>Zend_Search_Lucene_Document_Html->getHTML()</code> Methode empfangen.
- </para>
- <note>
- <para>
- Highlighting wird in den Ausdrücken des aktuellen Analysators durchgeführt. So
- werden alle Formen des Wortes/der Wörter vom Analysator erkannt und highgelighted.
- </para>
- <para>
- Z.B. wenn der aktuelle Analysator unabhängig von der Groß- oder Kleinschreibung ist
- und wir das Highlighten des Wortes 'text' anfragen, dann werden 'text', 'Text',
- 'TEXT' und alle anderen Kombinationen von Schreibweisen geHighlightet.
- </para>
- <para>
- Auf dem gleichen Weg wird, wenn der aktuelle Analysator Abstammung unterstützt und
- wir das Highlighten von 'indexed' anfragen, dann werden 'index', 'indexing',
- 'indices' und andere Formen dieser Wörter geHighlighted.
- </para>
- <para>
- Wenn andererseits das Wort vom aktuellen Analysator übersprungen wird (z.B. wenn
- ein Filter für kurze Wörter dem Analysator angehängt ist), dann wird nichts
- geHighlighted.
- </para>
- </note>
- <para>
- Die zweite Option ist die Verwendung der
- <code>Zend_Search_Lucene_Search_Query->highlightMatches(string $inputHTML[,
- $defaultEncoding = 'UTF-8'[,
- Zend_Search_Lucene_Search_Highlighter_Interface $highlighter]])</code> Methode:
- </para>
- <programlisting language="php"><![CDATA[
- query = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
- highlightedHTML = $query->highlightMatches($sourceHTML);
- ]]></programlisting>
- <para>
- Der optionale zweite Parameter ist die standardmäßige Kodierung des
- <acronym>HTML</acronym> Dokuments. Er wird verwendet wenn die Kodierung nicht, durch
- die Verwendung des Content-type MetaTags HTTP-EQUIV, spezifiziert ist.
- </para>
- <para>
- Der optionale dritte Parameter ist ein Highlighter Objekt welches das
- <classname>Zend_Search_Lucene_Search_Highlighter_Interface</classname> Interface
- implementiert:
- </para>
- <programlisting language="php"><![CDATA[
- interface Zend_Search_Lucene_Search_Highlighter_Interface
- {
- /**
- * Set document for highlighting.
- *
- * @param Zend_Search_Lucene_Document_Html $document
- */
- public function setDocument(Zend_Search_Lucene_Document_Html $document);
- /**
- * Get document for highlighting.
- *
- * @return Zend_Search_Lucene_Document_Html $document
- */
- public function getDocument();
- /**
- * Highlight specified words (method is invoked once per subquery)
- *
- * @param string|array $words Words to highlight. They could be
- organized using the array or string.
- */
- public function highlight($words);
- }
- ]]></programlisting>
- <para>
- Wobei das <code>Zend_Search_Lucene_Document_Html</code> Objekt ein Objekt ist welches
- von der HMTL Quelle erzeugt wird, die wiederum von der
- <code>Zend_Search_Lucene_Search_Query->highlightMatches()</code> Methode geliefert
- wird.
- </para>
- <para>
- Wenn der <varname>$highlighter</varname> Parameter nicht angegeben wird, dann wird das
- <code>Zend_Search_Lucene_Search_Highlighter_Default</code> Objekt initiiert und
- verwendet.
- </para>
- <para>
- Die Highlighter Methode <methodname>highlight()</methodname> ist einmal pro SubQuery
- enthalten, deshalb hat sie für diese auch die Möglichkeit das Highlightig zu
- unterscheiden.
- </para>
- <para>
- Aktuell, macht der standardmäßige Highlighter das indem eine vordefinierte Farbtabelle
- durchlaufen wird. Man kann also seinen eigenen Highlighter implementieren, oder den
- standardmäßigen nur erweitern und die Farbtabelle umdefinieren.
- </para>
- <para>
- <code>Zend_Search_Lucene_Search_Query->htmlFragmentHighlightMatches()</code>
- hat ein ähnliches Verhalten. Der einzige Unterschied besteht darin das er eine
- Eingabe entgegen nimmt, und <acronym>HTML</acronym> Fragmente ohne die <>HTML>,
- <HEAD>, <BODY> Tags zurückgibt. Trotzdem werden Fragmente automatisch in gültiges
- <acronym>XHTML</acronym> transformiert.
- </para>
- </sect2>
- </sect1>
|