Zend_Search_Lucene-Extending.xml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <sect1 id="zend.search.lucene.extending">
  2. <title>Uitbreidbaarheid</title>
  3. <sect2 id="zend.search.lucene.extending.analysis">
  4. <title>Tekst analysator</title>
  5. <para>
  6. De <code>Zend_Search_Lucene_Analysis_Analyzer</code> klasse wordt gebruikt door de indexer
  7. om tekstvelden van het document van tokens te voorzien.
  8. </para>
  9. <para>
  10. De <code>Zend_Search_Lucene_Analysis_Analyzer::getDefault()</code> en <code>Zend_Search_Lucene_Analysis_Analyzer::setDefault()</code> methodes worden gebruikt om de
  11. standaard analysator te verkrijgen of te zetten.
  12. </para>
  13. <para>
  14. Je kan dus je eigen tekst analysator aanwijzen of er één kiezen uit de aangeboden set van analysators:
  15. <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text</code> en <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code> (standaard).
  16. Beiden interpreteren tokens als een opeenvolging van letters. <code>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</code> past tokens aan
  17. naar kleine letters.
  18. </para>
  19. <para>
  20. Om tussen analysatoren te wisselen kan je de volgende code gebruiken:
  21. </para>
  22. <programlisting role="php"><![CDATA[<?php
  23. Zend_Search_Lucene_Analysis_Analyzer::setDefault(
  24. new Zend_Search_Lucene_Analysis_Analyzer_Common_Text());
  25. ...
  26. $index->addDocument($doc);
  27. ?>]]></programlisting>
  28. <para>
  29. De <code>Zend_Search_Lucene_Analysis_Analyzer_Common</code> is ontworpen om de parent van alle door gebruikers gedefinieerde
  30. analysatoren te zijn. De gebruiker zou alleen de <code>tokenize()</code> methode moeten schrijven, die
  31. een string als input data moet aanvaarden en een array van tokens moet terugsturen.
  32. </para>
  33. <para>
  34. De <code>tokenize()</code> methode zou de <code>normalize()</code> methode op alle tokens moeten toepassen.
  35. Dit laat toe token filters te gebuiken met jouw analysator.
  36. </para>
  37. <para>
  38. Hier is een voorbeeld van een zelfgemaakte analysator, welke woorden met cijfers als termen aanvaardt:
  39. <example>
  40. <title>Custom tekst Analysator</title>
  41. <programlisting role="php"><![CDATA[<?php
  42. /** Dit is een zelfgemaakte tekst analysator, die woorden met cijfers als een enkele term beschouwt */
  43. /** Zend_Search_Lucene_Analysis_Analyzer_Common */
  44. require_once 'Zend/Search/Lucene/Analysis/Analyzer/Common.php';
  45. class My_Analyzer extends Zend_Search_Lucene_Analysis_Analyzer_Common
  46. {
  47. /**
  48. * Tekst van termtokens voorzien
  49. * Geeft een array van Zend_Search_Lucene_Analysis_Token objecten terug
  50. *
  51. * @param string $data
  52. * @return array
  53. */
  54. public function tokenize($data)
  55. {
  56. $tokenStream = array();
  57. $position = 0;
  58. while ($position < strlen($data)) {
  59. // spaties overslaan
  60. while ($position < strlen($data) && !ctype_alpha($data{$position}) && !ctype_digit($data{$position})) {
  61. $position++;
  62. }
  63. $termStartPosition = $position;
  64. // token lezen
  65. while ($position < strlen($data) && (ctype_alpha($data{$position}) || ctype_digit($data{$position}))) {
  66. $position++;
  67. }
  68. // Leeg token, einde van de stream.
  69. if ($position == $termStartPosition) {
  70. break;
  71. }
  72. $token = new Zend_Search_Lucene_Analysis_Token(substr($data,
  73. $termStartPosition,
  74. $position-$termStartPosition),
  75. $termStartPosition,
  76. $position);
  77. $tokenStream[] = $this->normalize($token);
  78. }
  79. return $tokenStream;
  80. }
  81. }
  82. Zend_Search_Lucene_Analysis_Analyzer::setDefault(
  83. new My_Analyzer());
  84. ?>]]></programlisting>
  85. </example>
  86. </para>
  87. </sect2>
  88. <sect2 id="zend.search.lucene.extending.scoring">
  89. <title>Score Algorithmes</title>
  90. <para>
  91. De score van een query <literal>q</literal> voor document <literal>d</literal>
  92. is als volgt gedefinieerd:
  93. </para>
  94. <para>
  95. <code>score(q,d) = sum( tf(t in d) * idf(t) * getBoost(t.field in d) * lengthNorm(t.field in d) ) *
  96. coord(q,d) * queryNorm(q)</code>
  97. </para>
  98. <para>
  99. tf(t in d) - <code>Zend_Search_Lucene_Search_Similarity::tf($freq)</code> - een score factor gebaseerd op
  100. de frequentie van een term of zin in een document.
  101. </para>
  102. <para>
  103. idf(t) - <code>Zend_Search_Lucene_Search_SimilaritySimilarity::tf($term, $reader)</code> - een score factor
  104. van een eenvoudige term voor de gespecificeerde index.
  105. </para>
  106. <para>
  107. getBoost(t.field in d) - boost factor voor het termveld.
  108. </para>
  109. <para>
  110. lengthNorm($term) - de normalisatiewaarde voor een veld, gegeven het totaal
  111. aantal termen in een veld. Deze waarde wordt opgeslagen met de index. Deze waarden,
  112. samen met de veldboosts, worden opgeslaan in een index en vermenigvuldigd in scores
  113. door de zoekcode voor hits op elk veld.
  114. </para>
  115. <para>
  116. Overeenkomsten op langere velden zijn minder precies, dus geven implementaties
  117. van deze methode meestal kleinere waarden terug als numTokens groot is, en
  118. grotere waarden als numTokens klein is.
  119. </para>
  120. <para>
  121. coord(q,d) - <code>Zend_Search_Lucene_Search_Similarity::coord($overlap, $maxOverlap)</code> - een score
  122. factor gebaseerd op de fractie van alle query termen dat een document bevat.
  123. </para>
  124. <para>
  125. De aanwezigheid van een groot deel van de query termen duidt een betere overeenkomst
  126. met de query aan, dus zullen implementaties van deze methode meestal grotere waarden
  127. teruggeven wanneer de ratio tussen deze parameters groot is en kleinere waarden wanneer
  128. de ratio ertussen klein is.
  129. </para>
  130. <para>
  131. queryNorm(q) - de normalizatiewaarde voor een query gegeven de som van de
  132. gewichten van elk van de querytermen in het vierkant. Het gewicht van elke query term
  133. wordt dan vermenigvuldigd met deze waarde.
  134. </para>
  135. <para>
  136. Dit beïnvloedt het ordenen niet, maar probeert enkel scores van verschillende queries
  137. vergelijkbaar te maken.
  138. </para>
  139. <para>
  140. Het scoring algoritme kan verpersoonlijkt worden door je eigen Similarity klasse te maken. Om
  141. dit te doen moet je de Zend_Search_Lucene_Search_Similarity klasse uitbreiden zoals hierna is
  142. gedefinieerd, en dan de <code>Zend_Search_Lucene_Search_Similarity::setDefault($similarity);</code>
  143. methode gebruiken om het tot standaard te zetten.
  144. </para>
  145. <programlisting role="php"><![CDATA[<?php
  146. class MySimilarity extends Zend_Search_Lucene_Search_Similarity {
  147. public function lengthNorm($fieldName, $numTerms) {
  148. return 1.0/sqrt($numTerms);
  149. }
  150. public function queryNorm($sumOfSquaredWeights) {
  151. return 1.0/sqrt($sumOfSquaredWeights);
  152. }
  153. public function tf($freq) {
  154. return sqrt($freq);
  155. }
  156. /**
  157. * Wordt nu niet gebruikt. Berekent het aandeel van een slordige zinovereenkomst,
  158. * gebaseerd op een edit afstand.
  159. */
  160. public function sloppyFreq($distance) {
  161. return 1.0;
  162. }
  163. public function idfFreq($docFreq, $numDocs) {
  164. return log($numDocs/(float)($docFreq+1)) + 1.0;
  165. }
  166. public function coord($overlap, $maxOverlap) {
  167. return $overlap/(float)$maxOverlap;
  168. }
  169. }
  170. $mySimilarity = new MySimilarity();
  171. Zend_Search_Lucene_Search_Similarity::setDefault($mySimilarity);
  172. ?>]]></programlisting>
  173. </sect2>
  174. <sect2 id="zend.search.lucene.extending.storage">
  175. <title>Opslag containers</title>
  176. <para>
  177. Een abstracte klasse Zend_Search_Lucene_Storage_Directory definieert mapfunctionaliteit.
  178. </para>
  179. <para>
  180. De Zend_Search_Lucene constructor gebruikt ofwel een string of een Zend_Search_Lucene_Storage_Directory object
  181. als input.
  182. </para>
  183. <para>
  184. De Zend_Search_Lucene_Storage_Directory_Filesystem klasse implementeert mapfunctionaliteit voor het
  185. bestandssyteem.
  186. </para>
  187. <para>
  188. Indien een string werd opgegeven als input voor de Zend_Search_Lucene constructor, zal de
  189. indexlezer (Zend_Search_Lucene object) het beschouwen als een bestandssysteempad en zelf een
  190. Zend_Search_Lucene_Storage_Directory_Filesystem object instantiëren.
  191. </para>
  192. <para>
  193. Je kan je eigen implementatiemap definiëren door de Zend_Search_Lucene_Storage_Directory klasse uit te breiden.
  194. </para>
  195. <para>
  196. Zend_Search_Lucene_Storage_Directory methodes:
  197. </para>
  198. <programlisting><![CDATA[<?php
  199. abstract class Zend_Search_Lucene_Storage_Directory {
  200. /**
  201. * Sluit de opslag.
  202. *
  203. * @return void
  204. */
  205. abstract function close();
  206. /**
  207. * Maakt een nieuw, leeg bestand in de map met gegeven $filename.
  208. *
  209. * @param string $name
  210. * @return void
  211. */
  212. abstract function createFile($filename);
  213. /**
  214. * Verwijdert een bestaande $filename uit de map.
  215. *
  216. * @param string $filename
  217. * @return void
  218. */
  219. abstract function deleteFile($filename);
  220. /**
  221. * Geeft true terug indien een bestand met gegeven $filename bestaat.
  222. *
  223. * @param string $filename
  224. * @return boolean
  225. */
  226. abstract function fileExists($filename);
  227. /**
  228. * Geeft de lengte terug van een bestand $filename in de map.
  229. *
  230. * @param string $filename
  231. * @return integer
  232. */
  233. abstract function fileLength($filename);
  234. /**
  235. * Geeft de UNIX timestamp terug van de laatste wijziging van $filename.
  236. *
  237. * @param string $filename
  238. * @return integer
  239. */
  240. abstract function fileModified($filename);
  241. /**
  242. * Hernoemt een bestaand bestand in de map.
  243. *
  244. * @param string $from
  245. * @param string $to
  246. * @return void
  247. */
  248. abstract function renameFile($from, $to);
  249. /**
  250. * Zet de gewijzigde tijd van $filename naar nu.
  251. *
  252. * @param string $filename
  253. * @return void
  254. */
  255. abstract function touchFile($filename);
  256. /**
  257. * Geeft een Zend_Search_Lucene_Storage_File object terug voor een gegeven $filename in de map.
  258. *
  259. * @param string $filename
  260. * @return Zend_Search_Lucene_Storage_File
  261. */
  262. abstract function getFileObject($filename);
  263. }
  264. ?>]]></programlisting>
  265. <para>
  266. De <code>getFileObject($filename)</code> methode van de Zend_Search_Lucene_Storage_Directory klasse geeft
  267. een Zend_Search_Lucene_Storage_File object terug.
  268. </para>
  269. <para>
  270. De abstrakte klasse Zend_Search_Lucene_Storage_File implementeert bestandsabstractie en voorziet in indexbestand
  271. leesprimitieven.
  272. </para>
  273. <para>
  274. Je moet ook de Zend_Search_Lucene_Storage_File klasse uitbreiden voor jouw Directory implementatie.
  275. </para>
  276. <para>
  277. Slechts twee methodes van de Zend_Search_Lucene_Storage_File klasse hoeven te worden overloaded in jouw implementatie:
  278. </para>
  279. <programlisting><![CDATA[<?php
  280. class MyFile extends Zend_Search_Lucene_Storage_File {
  281. /**
  282. * Zet de bestandpositie indicator en zet de bestandswijzer voort.
  283. * De nieuwe positie, berekend in bytes vanaf het begin van het
  284. * bestand, wordt verkregen door offset aan de door $whence aangegeven
  285. * positie te voegen, welke waarden als volgt zijn gedefinieerd::
  286. * SEEK_SET - Zet de positie gelijk aan offset bytes.
  287. * SEEK_CUR - Zet de positie aan de huidige lokatie plus offset.
  288. * SEEK_END - Zet de positie tot einde-van-bestand plus offset. (Om naar
  289. * een positie vòòr einde-van-bestand te gaan moet je een negatieve waarde
  290. * aan offset toekennen.)
  291. * Geeft 0 indien success; anders -1
  292. *
  293. * @param integer $offset
  294. * @param integer $whence
  295. * @return integer
  296. */
  297. public function seek($offset, $whence=SEEK_SET) {
  298. ...
  299. }
  300. /**
  301. * Lees $length bytes van het bestand en beweeg de bestandswijzer voort.
  302. *
  303. * @param integer $length
  304. * @return string
  305. */
  306. protected function _fread($length=1) {
  307. ...
  308. }
  309. }
  310. ?>]]></programlisting>
  311. </sect2>
  312. </sect1>
  313. <!--
  314. vim:se ts=4 sw=4 et:
  315. -->