| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- <?xml version="1.0" encoding="utf-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.search.lucene.searching">
- <title>Chercher dans un index</title>
- <sect2 id="zend.search.lucene.searching.query_building">
- <title>Construire des requêtes</title>
- <para>
- Il y a deux manières de chercher dans un index. La première
- utilise le parseur de requête pour construire une requête à partir
- d'une chaîne de caractères. La seconde consiste à créer vos
- propres requêtes par programme à l'aide de l'<acronym>API</acronym>
- <classname>Zend_Search_Lucene</classname>.
- </para>
- <para>
- Avant de choisir d'utiliser le parseur de requête fourni, veuillez
- considérer ce qui suit :
- <orderedlist>
- <listitem>
- <para>
- Si vous créez par programme une chaîne et qu'ensuite vous la passez dans
- le parseur de requêtes, vous devriez considérer la possibilité
- de construire vos requêtes directement avec l'<acronym>API</acronym> de
- requêtes. En règle générale, le parseur est fait pour le texte saisi par
- un utilisateur, pas pour du texte généré par programme.
- </para>
- </listitem>
- <listitem>
- <para>
- Les champs non "tokenizés" devraient de préférences être ajoutés
- directement aux requêtes et pas être passés dans le parseur. Si
- les valeurs d'un champ sont générées par programme, les clauses de
- requête pour ce champ devraient également être créées par programme.
- Un analyseur, utilisé par le parseur de requêtes, est modélisé pour
- convertir le texte saisi par l'utilisateur en des termes. Les valeurs
- générées par programme, telles que dates, mot-clés, etc. devraient être
- ajoutés avec l'<acronym>API</acronym> de requêtes.
- </para>
- </listitem>
- <listitem>
- <para>
- Dans un formulaire de requête, les champs de texte général devraient
- utiliser le parseur de requêtes. Tous les autres, tels qu'intervalles de
- dates, mot-clés, etc., seront de préférence ajoutés directement dans
- l'<acronym>API</acronym> de requêtes. Un champ avec une somme limitée de
- valeurs qui peut être défini dans un menu déroulant ne devrait pas être
- ajouté à une chaîne de requête qui serait ensuite parsée, mais devrait être
- ajouté en tant que clause de type 'TermQuery'.
- </para>
- </listitem>
- <listitem>
- <para>
- Les requêtes booléennes permettent au programmeur de combiner de manière
- logique deux ou plus requêtes en une seule. De fait, c'est le meilleur
- moyen d'ajouter des critères additionnels à une requête définie dans une
- chaîne (querystring).
- </para>
- </listitem>
- </orderedlist>
- </para>
- <para>
- Les deux manières utilisent la même méthode d'<acronym>API</acronym> pour chercher
- dans l'index :
- </para>
- <programlisting language="php"><![CDATA[
- $index = Zend_Search_Lucene::open('/data/my_index');
- $index->find($query);
- ]]></programlisting>
- <para>
- La méthode <methodname>Zend_Search_Lucene::find()</methodname> détermine automatiquement
- le type de données entrantes et utilise le parseur de requêtes ou construit un objet
- approprié à partir d''une donnée entrante de type chaîne de caractères.
- </para>
- <para>
- Il est important de noter que le parseur de requêtes utilise l'analyseur standard
- pour "tokenizer" les différentes partie d'une chaîne. Ainsi, toutes les transformations
- qui sont appliquées aux textes indexés le sont également aux chaînes de requête.
- </para>
- <para>
- L'analyseur standard peut transformer la chaîne de requête en minuscules pour
- gérer l'insensibilité à la casse, retirer les mots exclus (ou "stop-words"), et
- encapsuler les autres transformations.
- </para>
- <para>
- La méthode de l'<acronym>API</acronym> ne transforme ni ne filtre les termes entrant
- d'aucune façon. Elle est ainsi plus pratique pour les champs générés par le programme
- ou ceux qui ne sont pas "tokenizés".
- </para>
- <sect3 id="zend.search.lucene.searching.query_building.parsing">
- <title>Parsage de requêtes</title>
- <para>
- La méthode <methodname>Zend_Search_Lucene_Search_QueryParser::parse()</methodname>
- peut être utilisée pour parser des chaînes de requête en objets de requête.
- </para>
- <para>
- Cet objet de requête peut être utilisé dans une méthode de construction de requête de
- l'<acronym>API</acronym> pour combiner des requêtes entrées par l'utilisateur avec
- des requêtes générées par programme.
- </para>
- <para>
- Pour l'instant, dans certains cas c'est le seul moyen de chercher des valeurs dans
- des champs "non-tokenizés" :
- Actually, in some cases it's the only way to search for values within untokenized
- fields:
- <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>
- <para>
- La méthode <methodname>Zend_Search_Lucene_Search_QueryParser::parse()</methodname>
- prend également un paramètre optionnel d'encodage, qui permet de spécifier l'encodage
- de la chaîne de requête :
- <programlisting language="php"><![CDATA[
- $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr,
- 'iso-8859-5');
- ]]></programlisting>
- </para>
- <para>
- Si le paramètre d'encodage est omis, la locale courante est utilisée.
- </para>
- <para>
- Il est également possible de spécifier l'encodage par défaut de la chaîne
- de requête avec la méthode <methodname>Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding()</methodname> :
- <programlisting language="php"><![CDATA[
- Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('iso-8859-5');
- ...
- $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
- ]]></programlisting>
- </para>
- <para>
- <methodname>Zend_Search_Lucene_Search_QueryParser::getDefaultEncoding()</methodname>
- retourne la valeur actuelle de l'encodage par défaut d'une chaîne de requête (une
- chaîne vide signifiant "locale courante").
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.search.lucene.searching.results">
- <title>Résultats de recherche</title>
- <para>
- Le résultat de recherche est un tableau d'objets
- <classname>Zend_Search_Lucene_Search_QueryHit</classname>. Chacun d'eux a deux propriétés :
- <code>$hit->id</code> est un identifiant numérique de document dans l'index et
- <code>$hit->score</code> est le score du hit dans le résultat de recherche. Les résultats
- sont triés par score (descendant depuis le meilleur score).
- </para>
- <para>
- L'objet <classname>Zend_Search_Lucene_Search_QueryHit</classname> expose également
- chaque champ du <classname>Zend_Search_Lucene_Document</classname> trouvé dans la
- recherche en tant que propriété du hit. Dans l'exemple suivant, un hit est retourné avec
- deux champs du document correspondant : title et author.
- </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>
- Les champs stockés sont toujours retournés encodés en UTF-8.
- </para>
- <para>
- Optionnellement, l'objet original <classname>Zend_Search_Lucene_Document</classname>
- peut être retourné depuis le <classname>Zend_Search_Lucene_Search_QueryHit</classname>.
- Vous pouvez récupérer les parties stockées du document en utilisant la méthode
- <methodname>getDocument()</methodname> de l'objet index, puis les obtenir avec la
- méthode <methodname>getFieldValue()</methodname> :
- </para>
- <programlisting language="php"><![CDATA[
- $index = Zend_Search_Lucene::open('/data/my_index');
- $hits = $index->find($query);
- foreach ($hits as $hit) {
- // return Zend_Search_Lucene_Document object for this hit
- echo $document = $hit->getDocument();
- // return a Zend_Search_Lucene_Field object
- // from the Zend_Search_Lucene_Document
- echo $document->getField('title');
- // return the string value of the Zend_Search_Lucene_Field object
- echo $document->getFieldValue('title');
- // same as getFieldValue()
- echo $document->title;
- }
- ]]></programlisting>
- <para>
- Les champs disponibles dans l'objet <classname>Zend_Search_Lucene_Document</classname>
- sont déterminés lors de l'indexation. Les champs sont soit indexés, soit indexés et stockés
- dans le document par l'application d'indexage (p. ex. LuceneIndexCreation.jar).
- </para>
- <para>
- Notez que l'identité du document ('path' dans notre exemple) est également
- stocké dans l'index et doit être récupéré depuis l'index.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.results-limiting">
- <title>Limiter le nombre de résultats</title>
- <para>
- L'opération la plus lourde au niveau du calcul dans une recherche est la calculation
- des scores. Cela peut prendre plusieurs secondes pour un grand ensemble de résultats
- (dizaine de milliers de hits).
- </para>
- <para>
- <classname>Zend_Search_Lucene</classname> donne la possibilité de limiter la taille
- de l'ensemble de résultats avec les méthodes <methodname>getResultSetLimit()</methodname>
- et <methodname>setResultSetLimit()</methodname> :
- <programlisting language="php"><![CDATA[
- $currentResultSetLimit = Zend_Search_Lucene::getResultSetLimit();
- Zend_Search_Lucene::setResultSetLimit($newLimit);
- ]]></programlisting>
- La valeur par défaut de 0 signifie 'pas de limite'.
- </para>
- <para>
- Cela ne retournera pas les 'N meilleurs' résultats, mais seulement les 'N premiers'.
- <footnote>
- <para>
- Les hits retournés demeurent triés par score ou par l'ordre spécifié, s'il est spécifié.
- </para>
- </footnote>.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.results-scoring">
- <title>Etablissement des scores des résultats de recherche</title>
- <para>
- <classname>Zend_Search_Lucene</classname> utilise le même algorithme de scoring que
- Java Lucene. Par défaut, tous les hits dans l'ensemble de résultats sont triés par score.
- Les hits avec le plus grand score viennent en premier, et les documents avec des hauts scores
- devraient mieux correspondre à la requête que ceux avec des scores moins élevés.
- </para>
- <para>
- En gros, les hits qui contiennent le terme ou la phrase cherché plus fréquemment
- auront un score plus élevé.
- </para>
- <para>
- Le score d'un hit peut être récupéré en accédant à la propriété <code>score</code> du hit :
- </para>
- <programlisting language="php"><![CDATA[
- $hits = $index->find($query);
- foreach ($hits as $hit) {
- echo $hit->id;
- echo $hit->score;
- }
- ]]></programlisting>
- <para>
- La classe <classname>Zend_Search_Lucene_Search_Similarity</classname> est utilisée
- pour calculer le score pour chaque hit. Consultez la section <link
- linkend="zend.search.lucene.extending.scoring">Extensibility. Scoring
- Algorithms</link> pour des détails.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.sorting">
- <title>Tri des résultats de recherche</title>
- <para>
- Par défaut, les résultats de recherche sont triés par score. Le programmeur peut
- changer ce comportement en définissant des paramètres pour le champ de tri (ou une liste de champs), le
- type de tri et le sens de tri.
- </para>
- <para>
- L'appel à <code>$index->find()</code> peut prendre plusieurs paramètres optionnels :
- <programlisting language="php"><![CDATA[
- $index->find($query [, $sortField [, $sortType [, $sortOrder]]]
- [, $sortField2 [, $sortType [, $sortOrder]]]
- ...);
- ]]></programlisting>
- </para>
- <para>
- Le nom d'un champ stocké par lequel on veut trier les résultats devrait
- être passé comme paramètre <varname>$sortField</varname>.
- </para>
- <para>
- <varname>$sortType</varname> peut être omis ou prendre l'une des valeurs suivantes :
- <constant>SORT_REGULAR</constant> (compare les éléments normalement- valeur par défaut),
- <constant>SORT_NUMERIC</constant> (compare les éléments comme des valeurs numériques),
- <constant>SORT_STRING</constant> (compare les éléments comme des chaînes de caractères).
- </para>
- <para>
- <varname>$sortOrder</varname> peut être omis ou prendre l'une des valeurs suivantes :
- <constant>SORT_ASC</constant> (trie dans l'ordre croissant- valeur par défaut),
- <constant>SORT_DESC</constant> (trie dans l'ordre décroissant).
- </para>
- <para>
- Exemples:
- <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>
- <para>
- Soyez prudents en personnalisant vos clés de tri; la requête aura besoin de récupérer
- tous les documents correspondant de l'index, ce qui peut réduire considérablement les
- performances de recherche.
- </para>
- </sect2>
- <sect2 id="zend.search.lucene.searching.highlighting">
- <title>Mise en évidence des résultats de recherche</title>
- <para>
- <classname>Zend_Search_Lucene</classname> propose deux options pour mettre en
- évidence les résultats de recherche.
- </para>
- <para>
- La première consiste à utiliser la classe <classname>Zend_Search_Lucene_Document_Html</classname>
- (voyez <link linkend="zend.search.lucene.index-creation.html-documents">la section
- Documents HTML</link> pour des détails) en utilisant les méthodes suivantes :
- <programlisting language="php"><![CDATA[
- /**
- * Mise en évidence de texte avec la couleur spécifiée
- *
- * @param string|array $words
- * @param string $colour
- * @return string
- */
- public function highlight($words, $colour = '#66ffff');
- ]]></programlisting>
- <programlisting language="php"><![CDATA[
- /**
- * Mise en évidence du texte en utilisant le View helper spécifié ou une
- * fonction callback.
- *
- * @param string|array $words Les mots à mettre en évidence. Ils peuvent être organisés
- dans un tableau ou une chaîne de caractères.
- * @param callback $callback La méthode callback, utilisée pour transformer
- (mettre en évidence) le texte.
- * @param array $params Un tableau de paramètres additionnels passés à la fonction
- callback (le premier paramètre non optionnel est un fragment
- de code HTML pour la mise en évidence).
- * @return string
- * @throws Zend_Search_Lucene_Exception
- */
- public function highlightExtended($words, $callback, $params = array())
- ]]></programlisting>
- </para>
- <para>
- Pour personnaliser le comportement de mise en évidence, utilisez la méthode
- <methodname>highlightExtended()</methodname> avec le callback spécifié qui prendra
- un ou plusieurs paramètres.
- <footnote>
- <para>
- Le premier paramètre est un fragment de code HTML pour la mise en évidence et
- les suivants sont dépendants du comportement du callback. La valeur de retour
- est un fragment HTML mise en évidence.
- </para>
- </footnote>
- , ou étendez la classe <classname>Zend_Search_Lucene_Document_Html</classname> et
- redéfinissez la méthode <methodname>applyColour($stringToHighlight, $colour)</methodname>
- qui est utilisée comme le callback de mise en évidence par défaut.
- <footnote>
- <para>
- Dans les deux cas, le HTML retourné est automatiquement transformé en
- <acronym>XHTML</acronym> valide.
- </para>
- </footnote>
- </para>
- <para>
- Les <link linkend="zend.view.helpers">View helpers</link> peuvent également être utilisés
- comme des callbacks dans un contexte d'affichage du script :
- <programlisting language="php"><![CDATA[
- $doc->highlightExtended('word1 word2 word3...', array($this, 'myViewHelper'));
- ]]></programlisting>
- </para>
- <para>
- Le résultat de l'opération de mise en évidence est récupéré avec
- la méthode <code>Zend_Search_Lucene_Document_Html->getHTML()</code>.
- </para>
- <note>
- <para>
- La mise en évidence est exécutée dans les termes de l'analyseur courant. Donc toutes
- les formes de mot(s) reconnues par l'analyseur seront mises en évidence.
- </para>
- <para>
- Ex.: Si l'analyseur courant est insensible à la casse et que l'on demande à mettre
- en évidence le mot 'text', alors 'text', 'Text', 'TEXT' ou toute autre combinaison de
- casse seront mis en évidence.
- </para>
- <para>
- Dans le même ordre d'idées, si l'analyseur courant supporte les requêtes proches (stemming)
- et que l'on souhaite mettre en évidence 'indexed', alors 'index', 'indexing', 'indices' et
- d'autres mots proches seront mis en évidences.
- </para>
- <para>
- A l'inverse, si un mot est ignoré par l'analyseur courant (ex. si un filtre pour
- ignorer les mots trop courts est appliqué à l'analyseur), alors rien ne sera mis en évidence.
- </para>
- </note>
- <para>
- La seconde option est d'utiliser la méthode
- <code>Zend_Search_Lucene_Search_Query->highlightMatches(string $inputHTML[,
- $defaultEncoding = 'UTF-8'[,
- Zend_Search_Lucene_Search_Highlighter_Interface $highlighter]])</code>:
- <programlisting language="php"><![CDATA[
- $query = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
- $highlightedHTML = $query->highlightMatches($sourceHTML);
- ]]></programlisting>
- </para>
- <para>
- Le second paramètre optionnel est l'encodage par défaut du document HTML. Il est
- utilisé si l'encodage n'est pas spécifié dans le metatag HTTP-EQUIV Content-Type.
- </para>
- <para>
- Le troisième paramètre optionnel est un objet de mise en évidence qui doit
- implémenter l'interface <classname>Zend_Search_Lucene_Search_Highlighter_Interface</classname>:
- <programlisting language="php"><![CDATA[
- interface Zend_Search_Lucene_Search_Highlighter_Interface
- {
- /**
- * Définit le document pour la mise en évidence
- *
- * @param Zend_Search_Lucene_Document_Html $document
- */
- public function setDocument(Zend_Search_Lucene_Document_Html $document);
- /**
- * Récupère le document pour la mise en évidence
- *
- * @return Zend_Search_Lucene_Document_Html $document
- */
- public function getDocument();
- /**
- * Mise en évidence des mots spécifiés (appelée une fois par sous-requête)
- *
- * @param string|array $words Les mots à mettre en évidence. Ils peuvent être organisés
- * dans un tableau ou une chaîne de caractères.
- */
- public function highlight($words);
- }
- ]]></programlisting>
- Où l'objet <classname>Zend_Search_Lucene_Document_Html</classname> est un objet
- construit à partir de la source HTML fournie par la méthode
- <classname>Zend_Search_Lucene_Search_Query->highlightMatches()</classname>
- </para>
- <para>
- Si le paramètre <varname>$highlighter</varname> est omis, un objet
- <classname>Zend_Search_Lucene_Search_Highlighter_Default</classname> est
- instancié et utilisé.
- </para>
- <para>
- La méthode de mise en évidence <methodname>highlight()</methodname> est invoquée une
- fois par sous-requête, ainsi elle a la possibilité de différencier la mise en évidence
- pour chacune.
- </para>
- <para>
- La mise en évidence par défaut le fait en parcourant une table prédéfinie de couleurs.
- Vous pouvez implémenter votre propre classe de mise en évidence ou juste étendre la classe
- par défaut et redéfinir la table de couleurs.
- </para>
- <para>
- <code>Zend_Search_Lucene_Search_Query->htmlFragmentHighlightMatches()</code> a un comportement
- similaire. La seule différence est qu'il prend en entrée et retourne un fragment HTML sans
- les balises <>HTML>, <HEAD>, <BODY>. Néanmoins, le fragment est automatiquement
- transformé en <acronym>XHTML</acronym> valide.
- </para>
- </sect2>
- </sect1>
|