[MANUAL] English:
[zend.git] / documentation / manual / ru / module_specs / Zend_Search_Lucene-Extending.xml
blobc58837b4c234561bac8e4c0c35fd0b2d10722613
1 <sect1 id="zend.search.lucene.extending">
2     <title>Расширяемость<!--Extensibility--></title>
4     <sect2 id="zend.search.lucene.extending.analysis">
5         <title>Анализ текста<!--Text Analysis--></title>
6         <para>
7             Класс <code>Zend_Search_Lucene_Analysis_Analyzer</code> используется
8             индексатором для разбиения текстовых полей документа на лексемы.
9 <!--
10             <code>Zend_Search_Lucene_Analysis_Analyzer</code> class is used by indexer to tokenize document
11             text fields.
12 -->
13         </para>
15         <para>
16             Методы
17             <code>Zend_Search_Lucene_Analysis_Analyzer::getDefault()</code> и
18             <code>Zend_Search_Lucene_Analysis_Analyzer::setDefault()</code>
19             используются для получения и установки анализатора по умолчанию.
20 <!--
21             <code>Zend_Search_Lucene_Analysis_Analyzer::getDefault()</code> and <code>
22             Zend_Search_Lucene_Analysis_Analyzer::setDefault()</code> methods are used
23             to get and set default analyzer.
24 -->
25         </para>
27         <para>
28             Таким образом, вы можете устанавливать собственный анализатор текста
29             или выбирать его из ряда предопределенных анализаторов:
30             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text</code> и
31             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code>
32             (по умолчанию). Оба интерпретируют лексему как последовательность
33             букв. <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code>
34             приводит лексемы к нижнему регистру.
35 <!--
36             Thus you can assign your own text analyzer or choose it from the set of predefined analyzers:
37             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text</code> and
38             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code> (default).
39             Both of them interpret token as a sequence of letters.
40             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code>
41             converts tokens to lower case.
42 -->
43         </para>
45         <para>
46             Переключение между анализаторами:
47 <!--
48             To switch between analyzers:
49 -->
50         </para>
52         <programlisting language="php"><![CDATA[<?php
53 Zend_Search_Lucene_Analysis_Analyzer::setDefault(
54     new Zend_Search_Lucene_Analysis_Analyzer_Common_Text());
55 ...
56 $index->addDocument($doc);]]></programlisting>
58         <para>
59             <code>Zend_Search_Lucene_Analysis_Analyzer_Common</code>
60             спроектирован для того, чтобы быть родительским классом для всех
61             анализаторов, определяемых пользователем. В наследующем классе
62             достаточно определить методы <code>reset()</code> и
63             <code>nextToken()</code>, которые берут строку из свойства $_input
64             и возвращают лексемы шаг за шагом (<constant>NULL</constant> означает конец
65             потока).
66 <!--
67             <code>Zend_Search_Lucene_Analysis_Analyzer_Common</code> is designed to be a parent for all user
68             defined analyzers. User should only define the <code>reset()</code> and <code>nextToken()</code> methods,
69             which take string from $_input member and returns tokens step by step
70             (<constant>NULL</constant> indicates end of stream).
71 -->
72         </para>
74         <para>
75             Метод <code>nextToken()</code> должен использовать метод
76             <code>normalize()</code> для каждой лексемы. Это позволит
77             использовать фильтры лексем с вашим анализатором.
78 <!--
79             The <code>nextToken()</code> method should apply the <code>normalize()</code> method to each
80             token. It will allow you to use token filters with your analyzer.
81 -->
82         </para>
84         <para>
85             Ниже приведен пример пользовательского анализатора, котрорый
86             принимает слова с цифрами как элементы:
87 <!--
88             Here is an example of a custom Analyzer, which takes words with digits as terms:
89 -->
91             <example>
92                 <title>Собственный анализатор текста<!--Custom text Analyzer.--></title>
93                 <programlisting language="php"><![CDATA[<?php
94 /** Это созданный пользователем текстовый анализатор, который интерпретирует слова с цифрами как один элемент. */
96 /** Zend_Search_Lucene_Analysis_Analyzer hierarchy */
97 require_once 'Zend/Search/Lucene/Analysis/Analyzer.php';
99 class My_Analyzer extends Zend_Search_Lucene_Analysis_Analyzer_Common
101     private $_position;
103     /**
104      * Установка позиции в начальное состояние
105      */
106     public function reset()
107     {
108         $this->_position = 0;
109     }
111     /**
112      * API для разбиения на лексемы
113      * Получение следующей лексемы
114      * Возвращает null, если достигнут конец потока
115      *
116      * @return Zend_Search_Lucene_Analysis_Token|null
117      */
118     public function nextToken()
119     {
120         if ($this->_input === null) {
121             return null;
122         }
124         while ($this->_position < strlen($this->_input)) {
125             // пропуск пробела
126             while ($this->_position < strlen($this->_input) &&
127                    !ctype_alnum( $this->_input[$this->_position] )) {
128                 $this->_position++;
129             }
131             $termStartPosition = $this->_position;
133             // чтение лексемы
134             while ($this->_position < strlen($this->_input) &&
135                    ctype_alnum( $this->_input[$this->_position] )) {
136                 $this->_position++;
137             }
139             // Пустая лексема, конец потока
140             if ($this->_position == $termStartPosition) {
141                 return null;
142             }
144             $token = new Zend_Search_Lucene_Analysis_Token(
145                                       substr($this->_input,
146                                              $termStartPosition,
147                                              $this->_position - $termStartPosition),
148                                       $termStartPosition,
149                                       $this->_position);
150             $token = $this->normalize($token);
151             if ($token !== null) {
152                 return $token;
153             }
154             // Продолжение, если лексема пропущена
155         }
157         return null;
158     }
161 Zend_Search_Lucene_Analysis_Analyzer::setDefault(
162     new My_Analyzer());]]></programlisting>
163             </example>
164         </para>
165     </sect2>
167     <sect2 id="zend.search.lucene.extending.filters">
168         <title>Фильтрация лексем<!--Tokens Filtering--></title>
169         <para>
170             Анализатор <code>Zend_Search_Lucene_Analysis_Analyzer_Common</code>
171             также предоставляет механизм фильтрации лексем.
172 <!--
173             <code>Zend_Search_Lucene_Analysis_Analyzer_Common</code> analyzer also offers tokens filtering
174             mechanism.
176         </para>
178         <para>
179             Класс <code>Zend_Search_Lucene_Analysis_TokenFilter</code> является
180             уровнем абстракции для таких фильтров. Он должен использоваться как
181             предок для ваших собственных фильтров.
182 <!--
183             <code>Zend_Search_Lucene_Analysis_TokenFilter</code> class is an abstract level for such filters.
184             It should be used as an ancestor for your own filters.
186         </para>
188         <para>
189             Пользовательские фильтры должны реализовать метод
190             <code>normalize()</code>, который может преобразовывать лексему или
191             сигнализировать, что лексема должна быть пропущена.
192 <!--
193             Custom filter must implement <code>normalize()</code> method which may transform input token or signal that
194             token should be skipped.
196         </para>
198         <para>
199             В предоставляемом анализаторе уже определены три фильтра:
200 <!--
201             There are three filters already defined in Analysis subpackage:
203             <itemizedlist>
204                 <listitem>
205                     <para>
206                         <code>Zend_Search_Lucene_Analysis_TokenFilter_LowerCase</code>
207 <!--
208                         <code>Zend_Search_Lucene_Analysis_TokenFilter_LowerCase</code> filter.
210                     </para>
211                 </listitem>
212                 <listitem>
213                     <para>
214                         <code>Zend_Search_Lucene_Analysis_TokenFilter_ShortWords</code>
215 <!--
216                         <code>Zend_Search_Lucene_Analysis_TokenFilter_ShortWords</code> filter.
218                     </para>
219                 </listitem>
220                 <listitem>
221                     <para>
222                         <code>Zend_Search_Lucene_Analysis_TokenFilter_StopWords</code>
223 <!--
224                         <code>Zend_Search_Lucene_Analysis_TokenFilter_StopWords</code> filter.
226                     </para>
227                 </listitem>
228             </itemizedlist>
229         </para>
231         <para>
232             Фильтр <code>LowerCase</code> уже используется для анализатора
233             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code>,
234             который применяется по умолчанию.
235 <!--
236             <code>LowerCase</code> filter is already used for
237             <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code> analyzer
238             which is default.
240         </para>
242         <para>
243             <code>ShortWords</code> и <code>StopWords</code> могут
244             использоваться с уже включенными анализаторами или вашими
245             собственными:
246 <!--
247             <code>ShortWords</code> and <code>StopWords</code> may be used with already defined or your own
248             analyzers like this:
250         </para>
252         <programlisting language="php"><![CDATA[<?php
253 $stopWords = array('a', 'an', 'at', 'the', 'and', 'or', 'is', 'am');
254 $stopWordsFilter = new Zend_Search_Lucene_Analysis_TokenFilter_StopWords($stopWords);
256 $analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive();
257 $analyzer->addFilter($stopWordsFilter);
259 Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);]]></programlisting>
261         <programlisting language="php"><![CDATA[<?php
262 $shortWordsFilter = new Zend_Search_Lucene_Analysis_TokenFilter_ShortWords();
264 $analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive();
265 $analyzer->addFilter($shortWordsFilter);
267 Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);]]></programlisting>
269         <para>
270             Конструктор
271             <code>Zend_Search_Lucene_Analysis_TokenFilter_StopWords</code>
272             принимает массив стоп-слов в качестве аргумента. Но стоп-слова можно
273             также загружать и из файла:
274 <!--
275             <code>Zend_Search_Lucene_Analysis_TokenFilter_StopWords</code> constructor takes an array of stop-words
276             as an input. But stop-words may be also loaded from a file:
278         </para>
280         <programlisting language="php"><![CDATA[<?php
281 $stopWordsFilter = new Zend_Search_Lucene_Analysis_TokenFilter_StopWords();
282 $stopWordsFilter->loadFromFile($my_stopwords_file);
284 $analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive();
285 $analyzer->addFilter($stopWordsFilter);
287 Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);]]></programlisting>
289         <para>
290             Файл должен быть текстовым с одним словом в каждой строке. Символом
291             '#' помечаются строки с комментариями.
292 <!--
293             File should be a common text file with one word in each string. '#' marks string as a comment.
295         </para>
297         <para>
298             Конструктор
299             <code>Zend_Search_Lucene_Analysis_TokenFilter_ShortWords</code>
300             имеет один необязательный параметр, это ограничение длины слова.
301             Его значение по умолчанию равно 2.
302 <!--
303             <code>Zend_Search_Lucene_Analysis_TokenFilter_ShortWords</code> constructor has one optional argument.
304             It's a words length limit. Default value is 2.
306         </para>
308     </sect2>
310     <sect2 id="zend.search.lucene.extending.scoring">
311         <title>Алгоритмы ранжирования<!--Scoring Algorithms--></title>
312         <para>
313             Ранг <literal>q</literal> документа
314             <literal>d</literal> определяется следующим образом:
315 <!--
316             The score of query <literal>q</literal> for document <literal>d</literal>
317             is defined as follows:
319         </para>
321         <para>
322             <code>score(q,d) = sum( tf(t in d) * idf(t) * getBoost(t.field in d) * lengthNorm(t.field in d)  ) *
323             coord(q,d) * queryNorm(q)</code>
324         </para>
326         <para>
327             tf(t in d) - <code>Zend_Search_Lucene_Search_Similarity::tf($freq)</code>
328             - коэффициент ранга, основанный на том, насколько часто встречается
329             элемент или фраза в документе.
330 <!--
331             tf(t in d) - <code>Zend_Search_Lucene_Search_Similarity::tf($freq)</code>
332             - a score factor based on a term or phrase's frequency in a document.
334         </para>
336         <para>
337             idf(t) - <code>Zend_Search_Lucene_Search_SimilaritySimilarity::tf($term, $reader)</code>
338             - коэффициент ранга для простого элемента применительно к определенному
339             индексу.
340 <!--
341             idf(t) - <code>Zend_Search_Lucene_Search_SimilaritySimilarity::tf($term, $reader)</code>
342             - a score factor for a simple term for the specified index.
344         </para>
346         <para>
347             getBoost(t.field in d) - коэффициент усиления для поля элемента.
348 <!--
349             getBoost(t.field in d) - boost factor for the term field.
351         </para>
353         <para>
354             lengthNorm($term) - значение нормализации для поля, получаемое из
355             общего количества элементов, содержащихся в поле. Это значение
356             хранится внутри индекса. Эти значения вместе с коэффициентом усиления поля
357             хранятся в индексе, результатом их умножения является
358             ранг для каждого поля.
359 <!--
360             lengthNorm($term) - the normalization value for a field given the total
361             number of terms contained in a field. This value is stored within the index.
362             These values, together with field boosts, are stored in an index and multiplied
363             into scores for hits on each field by the search code.
365         </para>
366         <para>
367             Совпадения в длинных полях менее точны, поэтому реализации этого метода
368             обычно возвращают тем меньшие значения, чем
369             больше число лексем, и тем большие значения, чем меньше число лексем.
370 <!--
371             Matches in longer fields are less precise, so implementations of this method
372             usually return smaller values when numTokens is large, and larger values when numTokens is small.
374         </para>
376         <para>
377             сoord(q,d) - <code>Zend_Search_Lucene_Search_Similarity::coord($overlap, $maxOverlap)</code>
378             - коэффициент ранга, основанный на относительной доле всех элементов запроса,
379             найденных в документе.
380 <!--
381             coord(q,d) - <code>Zend_Search_Lucene_Search_Similarity::coord($overlap, $maxOverlap)</code> - a
382             score factor based on the fraction of all query terms that a document contains.
384         </para>
386         <para>
387             Присутствие большого количества элементов запроса означает лучшее
388             соответствие запросу, поэтому реализации этого метода обычно возвращают
389             бОльшие значения, когда соотношение между этими параметрами большое
390             и меньшие значения, когда соотношение между ними небольшое.
391 <!--
392             The presence of a large portion of the query terms indicates a better match
393             with the query, so implementations of this method usually return larger values
394             when the ratio between these parameters is large and smaller values when
395             the ratio between them is small.
397         </para>
399         <para>
400             queryNorm(q) - значение нормализации для запроса, получаемое из суммы
401             возведенных в квадрат весов каждого из элементов запроса. Это значение
402             затем умножается в вес каждого элемента запроса.
403 <!--
404             queryNorm(q) -  the normalization value for a query given the sum of the squared weights
405             of each of the query terms. This value is then multiplied into the weight of each query
406             term.
408         </para>
410         <para>
411             Это не влияет на ранжирование, цель нормализации состоит в том, чтобы
412             сделать соизмеримыми ранги, полученные при различных запросах.
413 <!--
414             This does not affect ranking, but rather just attempts to make scores from different
415             queries comparable.
417         </para>
419         <para>
420             Алгоритм ранжирования может быть изменен через определение своего
421             собственного класса. Для этого надо создать потомка класса
422             Zend_Search_Lucene_Search_Similarity, как показано ниже, затем
423             использовать метод
424             <code>Zend_Search_Lucene_Search_Similarity::setDefault($similarity);</code>
425             для установки объекта как используемого по умолчанию.
426 <!--
427             Scoring algorithm can be customized by defining your own Similarity class. To do this
428             extend Zend_Search_Lucene_Search_Similarity class as defined below, then use
429             <code>Zend_Search_Lucene_Search_Similarity::setDefault($similarity);</code> method to set it as default.
431         </para>
433         <programlisting language="php"><![CDATA[<?php
435 class MySimilarity extends Zend_Search_Lucene_Search_Similarity {
436     public function lengthNorm($fieldName, $numTerms) {
437         return 1.0/sqrt($numTerms);
438     }
440     public function queryNorm($sumOfSquaredWeights) {
441         return 1.0/sqrt($sumOfSquaredWeights);
442     }
444     public function tf($freq) {
445         return sqrt($freq);
446     }
448     /**
449      * Сейчас не используется. Подсчитывает сумму соответствий неточной фразе,
450      * основанную на изменяемом расстоянии.
451      */
452     public function sloppyFreq($distance) {
453         return 1.0;
454     }
456     public function idfFreq($docFreq, $numDocs) {
457         return log($numDocs/(float)($docFreq+1)) + 1.0;
458     }
460     public function coord($overlap, $maxOverlap) {
461         return $overlap/(float)$maxOverlap;
462     }
465 $mySimilarity = new MySimilarity();
466 Zend_Search_Lucene_Search_Similarity::setDefault($mySimilarity);
468 ?>]]>  </programlisting>
469     </sect2>
471     <sect2 id="zend.search.lucene.extending.storage">
472         <title>Контейнеры хранения<!--Storage Containers--></title>
473         <para>
474         Абстрактный класс <code>Zend_Search_Lucene_Storage_Directory</code>
475         определяет функционал директории.
476 <!--
477         An abstract class <code>Zend_Search_Lucene_Storage_Directory</code> defines
478         directory functionality.
480         </para>
482         <para>
483         Конструктор <code>Zend_Search_Lucene</code> использует строку или
484         объект <code>Zend_Search_Lucene_Storage_Directory</code> как входные данные.
485 <!--
486         The <code>Zend_Search_Lucene</code> constructor uses either a string or a
487         <code>Zend_Search_Lucene_Storage_Directory</code> object
488         as an input.
490         </para>
492         <para>
493         <code>Zend_Search_Lucene_Storage_Directory_Filesystem</code> реализует
494         функционал директории для файловой системы.
495 <!--
496         <code>Zend_Search_Lucene_Storage_Directory_Filesystem</code> class implements directory
497         functionality for file system.
499         </para>
501         <para>
502         Если для конструктора <code>Zend_Search_Lucene</code> в качестве входных
503         данных испольуется строка, то считыватель индекса (объект
504         <code>Zend_Search_Lucene</code>) рассматривает ее как путь в файловой
505         системе и сама инстанцирует объекты
506         <code>Zend_Search_Lucene_Storage_Directory_Filesystem</code>.
507 <!--
508         If a string is used as an input for the <code>Zend_Search_Lucene</code> constructor, then the index
509         reader (<code>Zend_Search_Lucene</code> object) treats it as a file system path and instantiates
510         <code>Zend_Search_Lucene_Storage_Directory_Filesystem</code> objects by themselves.
512         </para>
514         <para>
515         Вы можете определить собственную реализацию директории,
516         создав потомка класса <code>Zend_Search_Lucene_Storage_Directory</code>.
517 <!--
518         You can define your own directory implementation by extending the
519         <code>Zend_Search_Lucene_Storage_Directory</code> class.
521         </para>
523         <para>
524         Методы <code>Zend_Search_Lucene_Storage_Directory</code>:
525 <!--
526         <code>Zend_Search_Lucene_Storage_Directory</code> methods:
528         </para>
530         <programlisting><![CDATA[<?php
532 abstract class Zend_Search_Lucene_Storage_Directory {
534  * Закрывает средство хранения.
536  * @return void
537  */
538 abstract function close();
542  * Создает новый пустой файл с данным именем в директории.
544  * @param string $name
545  * @return void
546  */
547 abstract function createFile($filename);
551  * Удаляет существующий файл в директории.
553  * @param string $filename
554  * @return void
555  */
556 abstract function deleteFile($filename);
560  * Возвращает true, если файл с данным именем существует.
562  * @param string $filename
563  * @return boolean
564  */
565 abstract function fileExists($filename);
569  * Возвращает длину файла в директории.
571  * @param string $filename
572  * @return integer
573  */
574 abstract function fileLength($filename);
578  * Возвращает время последнего изменения файла в формате UNIX.
580  * @param string $filename
581  * @return integer
582  */
583 abstract function fileModified($filename);
587  * Переименовывает существующий файл в директории.
589  * @param string $from
590  * @param string $to
591  * @return void
592  */
593 abstract function renameFile($from, $to);
597  * Устанавливает время изменения файла в текущее.
599  * @param string $filename
600  * @return void
601  */
602 abstract function touchFile($filename);
606  * Возвращает объект Zend_Search_Lucene_Storage_File для данного файла в директории.
608  * @param string $filename
609  * @return Zend_Search_Lucene_Storage_File
610  */
611 abstract function getFileObject($filename);
615 ?>]]></programlisting>
617         <para>
618         Метод <code>getFileObject($filename)</code> класса
619         <code>Zend_Search_Lucene_Storage_Directory</code> возвращает
620         объект <code>Zend_Search_Lucene_Storage_File</code>.
621 <!--
622         <code>getFileObject($filename)</code> method of <code>Zend_Search_Lucene_Storage_Directory</code>
623         class returns a <code>Zend_Search_Lucene_Storage_File</code> object.
625         </para>
626         <para>
627         Абстрактный класс <code>Zend_Search_Lucene_Storage_File</code> реализует
628         абстракцию файла и примитивы чтения файла индекса.
629 <!--
630         <code>Zend_Search_Lucene_Storage_File</code> abstract class implements file abstraction and index
631         file reading primitives.
633         </para>
634         <para>
635         Вы должны создать класс, наследующий от <code>Zend_Search_Lucene_Storage_File</code>
636         для своей реализации директории.
637 <!--
638         You must also extend <code>Zend_Search_Lucene_Storage_File</code> for your Directory implementation.
640         </para>
641         <para>
642         Только два метода класса <code>Zend_Search_Lucene_Storage_File</code> должны быть
643         перегружены в вашей реализации:
644 <!--
645         Only two methods of <code>Zend_Search_Lucene_Storage_File</code> must be overloaded in your
646         implementation:
648         </para>
650         <programlisting><![CDATA[<?php
652 class MyFile extends Zend_Search_Lucene_Storage_File {
653     /**
654      * Устанавливает индикатор позиции и перемещает указатель файла.
655      * Новая позиция, измеряемая в байтах от начала файла,
656      * получается добавлением смещения к позиции, определяемой аргументом $whence,
657      * который может принимать следующие значения:
658      * SEEK_SET - Устанавливает позицию равной смещению в байтах.
659      * SEEK_CUR - Устанавливает позицию равной текущей позиции плюс смещение.
660      * SEEK_END - Устанавливает позицию равной концу файла плюс смещение.
661      * (Для перемещения позиции относительно конца файла вы должны передать отрицательное значение смещения)
662      * В случае успеха возвращает 0; иначе -1
663      *
664      * @param integer $offset
665      * @param integer $whence
666      * @return integer
667      */
668     public function seek($offset, $whence=SEEK_SET) {
669         ...
670     }
672     /**
673      * Считывает $length байт из файла и перемещает указатель файла.
674      *
675      * @param integer $length
676      * @return string
677      */
678     protected function _fread($length=1) {
679         ...
680     }
683 ?>]]></programlisting>
685     </sect2>
686 </sect1>
688 <!--
689 vim:se ts=4 sw=4 et: