PageRenderTime 39ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/concreteOLD/libraries/3rdparty/Zend/Search/Lucene/MultiSearcher.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 973 lines | 887 code | 11 blank | 75 comment | 2 complexity | dfa9f6fe8beb5ccf4c89ded56b36ac0b MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Search_Lucene
  17. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: MultiSearcher.php 23775 2011-03-01 17:25:24Z ralph $
  20. */
  21. /** Zend_Search_Lucene_Interface */
  22. require_once 'Zend/Search/Lucene/Interface.php';
  23. /**
  24. * Multisearcher allows to search through several independent indexes.
  25. *
  26. * @category Zend
  27. * @package Zend_Search_Lucene
  28. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class Zend_Search_Lucene_Interface_MultiSearcher implements Zend_Search_Lucene_Interface
  32. {
  33. /**
  34. * List of indices for searching.
  35. * Array of Zend_Search_Lucene_Interface objects
  36. *
  37. * @var array
  38. */
  39. protected $_indices;
  40. /**
  41. * Object constructor.
  42. *
  43. * @param array $indices Arrays of indices for search
  44. * @throws Zend_Search_Lucene_Exception
  45. */
  46. public function __construct($indices = array())
  47. {
  48. $this->_indices = $indices;
  49. foreach ($this->_indices as $index) {
  50. if (!$index instanceof Zend_Search_Lucene_Interface) {
  51. require_once 'Zend/Search/Lucene/Exception.php';
  52. throw new Zend_Search_Lucene_Exception('sub-index objects have to implement Zend_Search_Lucene_Interface.');
  53. }
  54. }
  55. }
  56. /**
  57. * Add index for searching.
  58. *
  59. * @param Zend_Search_Lucene_Interface $index
  60. */
  61. public function addIndex(Zend_Search_Lucene_Interface $index)
  62. {
  63. $this->_indices[] = $index;
  64. }
  65. /**
  66. * Get current generation number
  67. *
  68. * Returns generation number
  69. * 0 means pre-2.1 index format
  70. * -1 means there are no segments files.
  71. *
  72. * @param Zend_Search_Lucene_Storage_Directory $directory
  73. * @return integer
  74. * @throws Zend_Search_Lucene_Exception
  75. */
  76. public static function getActualGeneration(Zend_Search_Lucene_Storage_Directory $directory)
  77. {
  78. require_once 'Zend/Search/Lucene/Exception.php';
  79. throw new Zend_Search_Lucene_Exception("Generation number can't be retrieved for multi-searcher");
  80. }
  81. /**
  82. * Get segments file name
  83. *
  84. * @param integer $generation
  85. * @return string
  86. */
  87. public static function getSegmentFileName($generation)
  88. {
  89. return Zend_Search_Lucene::getSegmentFileName($generation);
  90. }
  91. /**
  92. * Get index format version
  93. *
  94. * @return integer
  95. * @throws Zend_Search_Lucene_Exception
  96. */
  97. public function getFormatVersion()
  98. {
  99. require_once 'Zend/Search/Lucene/Exception.php';
  100. throw new Zend_Search_Lucene_Exception("Format version can't be retrieved for multi-searcher");
  101. }
  102. /**
  103. * Set index format version.
  104. * Index is converted to this format at the nearest upfdate time
  105. *
  106. * @param int $formatVersion
  107. */
  108. public function setFormatVersion($formatVersion)
  109. {
  110. foreach ($this->_indices as $index) {
  111. $index->setFormatVersion($formatVersion);
  112. }
  113. }
  114. /**
  115. * Returns the Zend_Search_Lucene_Storage_Directory instance for this index.
  116. *
  117. * @return Zend_Search_Lucene_Storage_Directory
  118. */
  119. public function getDirectory()
  120. {
  121. require_once 'Zend/Search/Lucene/Exception.php';
  122. throw new Zend_Search_Lucene_Exception("Index directory can't be retrieved for multi-searcher");
  123. }
  124. /**
  125. * Returns the total number of documents in this index (including deleted documents).
  126. *
  127. * @return integer
  128. */
  129. public function count()
  130. {
  131. $count = 0;
  132. foreach ($this->_indices as $index) {
  133. $count += $index->count();
  134. }
  135. return $count;
  136. }
  137. /**
  138. * Returns one greater than the largest possible document number.
  139. * This may be used to, e.g., determine how big to allocate a structure which will have
  140. * an element for every document number in an index.
  141. *
  142. * @return integer
  143. */
  144. public function maxDoc()
  145. {
  146. return $this->count();
  147. }
  148. /**
  149. * Returns the total number of non-deleted documents in this index.
  150. *
  151. * @return integer
  152. */
  153. public function numDocs()
  154. {
  155. $docs = 0;
  156. foreach ($this->_indices as $index) {
  157. $docs += $index->numDocs();
  158. }
  159. return $docs;
  160. }
  161. /**
  162. * Checks, that document is deleted
  163. *
  164. * @param integer $id
  165. * @return boolean
  166. * @throws Zend_Search_Lucene_Exception Exception is thrown if $id is out of the range
  167. */
  168. public function isDeleted($id)
  169. {
  170. foreach ($this->_indices as $index) {
  171. $indexCount = $index->count();
  172. if ($indexCount > $id) {
  173. return $index->isDeleted($id);
  174. }
  175. $id -= $indexCount;
  176. }
  177. require_once 'Zend/Search/Lucene/Exception.php';
  178. throw new Zend_Search_Lucene_Exception('Document id is out of the range.');
  179. }
  180. /**
  181. * Set default search field.
  182. *
  183. * Null means, that search is performed through all fields by default
  184. *
  185. * Default value is null
  186. *
  187. * @param string $fieldName
  188. */
  189. public static function setDefaultSearchField($fieldName)
  190. {
  191. foreach ($this->_indices as $index) {
  192. $index->setDefaultSearchField($fieldName);
  193. }
  194. }
  195. /**
  196. * Get default search field.
  197. *
  198. * Null means, that search is performed through all fields by default
  199. *
  200. * @return string
  201. * @throws Zend_Search_Lucene_Exception
  202. */
  203. public static function getDefaultSearchField()
  204. {
  205. if (count($this->_indices) == 0) {
  206. require_once 'Zend/Search/Lucene/Exception.php';
  207. throw new Zend_Search_Lucene_Exception('Indices list is empty');
  208. }
  209. $defaultSearchField = reset($this->_indices)->getDefaultSearchField();
  210. foreach ($this->_indices as $index) {
  211. if ($index->getDefaultSearchField() !== $defaultSearchField) {
  212. require_once 'Zend/Search/Lucene/Exception.php';
  213. throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
  214. }
  215. }
  216. return $defaultSearchField;
  217. }
  218. /**
  219. * Set result set limit.
  220. *
  221. * 0 (default) means no limit
  222. *
  223. * @param integer $limit
  224. */
  225. public static function setResultSetLimit($limit)
  226. {
  227. foreach ($this->_indices as $index) {
  228. $index->setResultSetLimit($limit);
  229. }
  230. }
  231. /**
  232. * Set result set limit.
  233. *
  234. * 0 means no limit
  235. *
  236. * @return integer
  237. * @throws Zend_Search_Lucene_Exception
  238. */
  239. public static function getResultSetLimit()
  240. {
  241. if (count($this->_indices) == 0) {
  242. require_once 'Zend/Search/Lucene/Exception.php';
  243. throw new Zend_Search_Lucene_Exception('Indices list is empty');
  244. }
  245. $defaultResultSetLimit = reset($this->_indices)->getResultSetLimit();
  246. foreach ($this->_indices as $index) {
  247. if ($index->getResultSetLimit() !== $defaultResultSetLimit) {
  248. require_once 'Zend/Search/Lucene/Exception.php';
  249. throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
  250. }
  251. }
  252. return $defaultResultSetLimit;
  253. }
  254. /**
  255. * Retrieve index maxBufferedDocs option
  256. *
  257. * maxBufferedDocs is a minimal number of documents required before
  258. * the buffered in-memory documents are written into a new Segment
  259. *
  260. * Default value is 10
  261. *
  262. * @return integer
  263. * @throws Zend_Search_Lucene_Exception
  264. */
  265. public function getMaxBufferedDocs()
  266. {
  267. if (count($this->_indices) == 0) {
  268. require_once 'Zend/Search/Lucene/Exception.php';
  269. throw new Zend_Search_Lucene_Exception('Indices list is empty');
  270. }
  271. $maxBufferedDocs = reset($this->_indices)->getMaxBufferedDocs();
  272. foreach ($this->_indices as $index) {
  273. if ($index->getMaxBufferedDocs() !== $maxBufferedDocs) {
  274. require_once 'Zend/Search/Lucene/Exception.php';
  275. throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
  276. }
  277. }
  278. return $maxBufferedDocs;
  279. }
  280. /**
  281. * Set index maxBufferedDocs option
  282. *
  283. * maxBufferedDocs is a minimal number of documents required before
  284. * the buffered in-memory documents are written into a new Segment
  285. *
  286. * Default value is 10
  287. *
  288. * @param integer $maxBufferedDocs
  289. */
  290. public function setMaxBufferedDocs($maxBufferedDocs)
  291. {
  292. foreach ($this->_indices as $index) {
  293. $index->setMaxBufferedDocs($maxBufferedDocs);
  294. }
  295. }
  296. /**
  297. * Retrieve index maxMergeDocs option
  298. *
  299. * maxMergeDocs is a largest number of documents ever merged by addDocument().
  300. * Small values (e.g., less than 10,000) are best for interactive indexing,
  301. * as this limits the length of pauses while indexing to a few seconds.
  302. * Larger values are best for batched indexing and speedier searches.
  303. *
  304. * Default value is PHP_INT_MAX
  305. *
  306. * @return integer
  307. * @throws Zend_Search_Lucene_Exception
  308. */
  309. public function getMaxMergeDocs()
  310. {
  311. if (count($this->_indices) == 0) {
  312. require_once 'Zend/Search/Lucene/Exception.php';
  313. throw new Zend_Search_Lucene_Exception('Indices list is empty');
  314. }
  315. $maxMergeDocs = reset($this->_indices)->getMaxMergeDocs();
  316. foreach ($this->_indices as $index) {
  317. if ($index->getMaxMergeDocs() !== $maxMergeDocs) {
  318. require_once 'Zend/Search/Lucene/Exception.php';
  319. throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
  320. }
  321. }
  322. return $maxMergeDocs;
  323. }
  324. /**
  325. * Set index maxMergeDocs option
  326. *
  327. * maxMergeDocs is a largest number of documents ever merged by addDocument().
  328. * Small values (e.g., less than 10,000) are best for interactive indexing,
  329. * as this limits the length of pauses while indexing to a few seconds.
  330. * Larger values are best for batched indexing and speedier searches.
  331. *
  332. * Default value is PHP_INT_MAX
  333. *
  334. * @param integer $maxMergeDocs
  335. */
  336. public function setMaxMergeDocs($maxMergeDocs)
  337. {
  338. foreach ($this->_indices as $index) {
  339. $index->setMaxMergeDocs($maxMergeDocs);
  340. }
  341. }
  342. /**
  343. * Retrieve index mergeFactor option
  344. *
  345. * mergeFactor determines how often segment indices are merged by addDocument().
  346. * With smaller values, less RAM is used while indexing,
  347. * and searches on unoptimized indices are faster,
  348. * but indexing speed is slower.
  349. * With larger values, more RAM is used during indexing,
  350. * and while searches on unoptimized indices are slower,
  351. * indexing is faster.
  352. * Thus larger values (> 10) are best for batch index creation,
  353. * and smaller values (< 10) for indices that are interactively maintained.
  354. *
  355. * Default value is 10
  356. *
  357. * @return integer
  358. * @throws Zend_Search_Lucene_Exception
  359. */
  360. public function getMergeFactor()
  361. {
  362. if (count($this->_indices) == 0) {
  363. require_once 'Zend/Search/Lucene/Exception.php';
  364. throw new Zend_Search_Lucene_Exception('Indices list is empty');
  365. }
  366. $mergeFactor = reset($this->_indices)->getMergeFactor();
  367. foreach ($this->_indices as $index) {
  368. if ($index->getMergeFactor() !== $mergeFactor) {
  369. require_once 'Zend/Search/Lucene/Exception.php';
  370. throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
  371. }
  372. }
  373. return $mergeFactor;
  374. }
  375. /**
  376. * Set index mergeFactor option
  377. *
  378. * mergeFactor determines how often segment indices are merged by addDocument().
  379. * With smaller values, less RAM is used while indexing,
  380. * and searches on unoptimized indices are faster,
  381. * but indexing speed is slower.
  382. * With larger values, more RAM is used during indexing,
  383. * and while searches on unoptimized indices are slower,
  384. * indexing is faster.
  385. * Thus larger values (> 10) are best for batch index creation,
  386. * and smaller values (< 10) for indices that are interactively maintained.
  387. *
  388. * Default value is 10
  389. *
  390. * @param integer $maxMergeDocs
  391. */
  392. public function setMergeFactor($mergeFactor)
  393. {
  394. foreach ($this->_indices as $index) {
  395. $index->setMaxMergeDocs($mergeFactor);
  396. }
  397. }
  398. /**
  399. * Performs a query against the index and returns an array
  400. * of Zend_Search_Lucene_Search_QueryHit objects.
  401. * Input is a string or Zend_Search_Lucene_Search_Query.
  402. *
  403. * @param mixed $query
  404. * @return array Zend_Search_Lucene_Search_QueryHit
  405. * @throws Zend_Search_Lucene_Exception
  406. */
  407. public function find($query)
  408. {
  409. if (count($this->_indices) == 0) {
  410. return array();
  411. }
  412. $hitsList = array();
  413. $indexShift = 0;
  414. foreach ($this->_indices as $index) {
  415. $hits = $index->find($query);
  416. if ($indexShift != 0) {
  417. foreach ($hits as $hit) {
  418. $hit->id += $indexShift;
  419. }
  420. }
  421. $indexShift += $index->count();
  422. $hitsList[] = $hits;
  423. }
  424. /** @todo Implement advanced sorting */
  425. return call_user_func_array('array_merge', $hitsList);
  426. }
  427. /**
  428. * Returns a list of all unique field names that exist in this index.
  429. *
  430. * @param boolean $indexed
  431. * @return array
  432. */
  433. public function getFieldNames($indexed = false)
  434. {
  435. $fieldNamesList = array();
  436. foreach ($this->_indices as $index) {
  437. $fieldNamesList[] = $index->getFieldNames($indexed);
  438. }
  439. return array_unique(call_user_func_array('array_merge', $fieldNamesList));
  440. }
  441. /**
  442. * Returns a Zend_Search_Lucene_Document object for the document
  443. * number $id in this index.
  444. *
  445. * @param integer|Zend_Search_Lucene_Search_QueryHit $id
  446. * @return Zend_Search_Lucene_Document
  447. * @throws Zend_Search_Lucene_Exception Exception is thrown if $id is out of the range
  448. */
  449. public function getDocument($id)
  450. {
  451. if ($id instanceof Zend_Search_Lucene_Search_QueryHit) {
  452. /* @var $id Zend_Search_Lucene_Search_QueryHit */
  453. $id = $id->id;
  454. }
  455. foreach ($this->_indices as $index) {
  456. $indexCount = $index->count();
  457. if ($indexCount > $id) {
  458. return $index->getDocument($id);
  459. }
  460. $id -= $indexCount;
  461. }
  462. require_once 'Zend/Search/Lucene/Exception.php';
  463. throw new Zend_Search_Lucene_Exception('Document id is out of the range.');
  464. }
  465. /**
  466. * Returns true if index contain documents with specified term.
  467. *
  468. * Is used for query optimization.
  469. *
  470. * @param Zend_Search_Lucene_Index_Term $term
  471. * @return boolean
  472. */
  473. public function hasTerm(Zend_Search_Lucene_Index_Term $term)
  474. {
  475. foreach ($this->_indices as $index) {
  476. if ($index->hasTerm($term)) {
  477. return true;
  478. }
  479. }
  480. return false;
  481. }
  482. /**
  483. * Returns IDs of all the documents containing term.
  484. *
  485. * @param Zend_Search_Lucene_Index_Term $term
  486. * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
  487. * @return array
  488. * @throws Zend_Search_Lucene_Exception
  489. */
  490. public function termDocs(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
  491. {
  492. if ($docsFilter != null) {
  493. require_once 'Zend/Search/Lucene/Exception.php';
  494. throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
  495. }
  496. $docsList = array();
  497. $indexShift = 0;
  498. foreach ($this->_indices as $index) {
  499. $docs = $index->termDocs($term);
  500. if ($indexShift != 0) {
  501. foreach ($docs as $id => $docId) {
  502. $docs[$id] += $indexShift;
  503. }
  504. }
  505. $indexShift += $index->count();
  506. $docsList[] = $docs;
  507. }
  508. return call_user_func_array('array_merge', $docsList);
  509. }
  510. /**
  511. * Returns documents filter for all documents containing term.
  512. *
  513. * It performs the same operation as termDocs, but return result as
  514. * Zend_Search_Lucene_Index_DocsFilter object
  515. *
  516. * @param Zend_Search_Lucene_Index_Term $term
  517. * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
  518. * @return Zend_Search_Lucene_Index_DocsFilter
  519. * @throws Zend_Search_Lucene_Exception
  520. */
  521. public function termDocsFilter(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
  522. {
  523. require_once 'Zend/Search/Lucene/Exception.php';
  524. throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
  525. }
  526. /**
  527. * Returns an array of all term freqs.
  528. * Return array structure: array( docId => freq, ...)
  529. *
  530. * @param Zend_Search_Lucene_Index_Term $term
  531. * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
  532. * @return integer
  533. * @throws Zend_Search_Lucene_Exception
  534. */
  535. public function termFreqs(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
  536. {
  537. if ($docsFilter != null) {
  538. require_once 'Zend/Search/Lucene/Exception.php';
  539. throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
  540. }
  541. $freqsList = array();
  542. $indexShift = 0;
  543. foreach ($this->_indices as $index) {
  544. $freqs = $index->termFreqs($term);
  545. if ($indexShift != 0) {
  546. $freqsShifted = array();
  547. foreach ($freqs as $docId => $freq) {
  548. $freqsShifted[$docId + $indexShift] = $freq;
  549. }
  550. $freqs = $freqsShifted;
  551. }
  552. $indexShift += $index->count();
  553. $freqsList[] = $freqs;
  554. }
  555. return call_user_func_array('array_merge', $freqsList);
  556. }
  557. /**
  558. * Returns an array of all term positions in the documents.
  559. * Return array structure: array( docId => array( pos1, pos2, ...), ...)
  560. *
  561. * @param Zend_Search_Lucene_Index_Term $term
  562. * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
  563. * @return array
  564. * @throws Zend_Search_Lucene_Exception
  565. */
  566. public function termPositions(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
  567. {
  568. if ($docsFilter != null) {
  569. require_once 'Zend/Search/Lucene/Exception.php';
  570. throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
  571. }
  572. $termPositionsList = array();
  573. $indexShift = 0;
  574. foreach ($this->_indices as $index) {
  575. $termPositions = $index->termPositions($term);
  576. if ($indexShift != 0) {
  577. $termPositionsShifted = array();
  578. foreach ($termPositions as $docId => $positions) {
  579. $termPositions[$docId + $indexShift] = $positions;
  580. }
  581. $termPositions = $termPositionsShifted;
  582. }
  583. $indexShift += $index->count();
  584. $termPositionsList[] = $termPositions;
  585. }
  586. return call_user_func_array('array_merge', $termPositions);
  587. }
  588. /**
  589. * Returns the number of documents in this index containing the $term.
  590. *
  591. * @param Zend_Search_Lucene_Index_Term $term
  592. * @return integer
  593. */
  594. public function docFreq(Zend_Search_Lucene_Index_Term $term)
  595. {
  596. $docFreq = 0;
  597. foreach ($this->_indices as $index) {
  598. $docFreq += $index->docFreq($term);
  599. }
  600. return $docFreq;
  601. }
  602. /**
  603. * Retrive similarity used by index reader
  604. *
  605. * @return Zend_Search_Lucene_Search_Similarity
  606. * @throws Zend_Search_Lucene_Exception
  607. */
  608. public function getSimilarity()
  609. {
  610. if (count($this->_indices) == 0) {
  611. require_once 'Zend/Search/Lucene/Exception.php';
  612. throw new Zend_Search_Lucene_Exception('Indices list is empty');
  613. }
  614. $similarity = reset($this->_indices)->getSimilarity();
  615. foreach ($this->_indices as $index) {
  616. if ($index->getSimilarity() !== $similarity) {
  617. require_once 'Zend/Search/Lucene/Exception.php';
  618. throw new Zend_Search_Lucene_Exception('Indices have different similarity.');
  619. }
  620. }
  621. return $similarity;
  622. }
  623. /**
  624. * Returns a normalization factor for "field, document" pair.
  625. *
  626. * @param integer $id
  627. * @param string $fieldName
  628. * @return float
  629. */
  630. public function norm($id, $fieldName)
  631. {
  632. foreach ($this->_indices as $index) {
  633. $indexCount = $index->count();
  634. if ($indexCount > $id) {
  635. return $index->norm($id, $fieldName);
  636. }
  637. $id -= $indexCount;
  638. }
  639. return null;
  640. }
  641. /**
  642. * Returns true if any documents have been deleted from this index.
  643. *
  644. * @return boolean
  645. */
  646. public function hasDeletions()
  647. {
  648. foreach ($this->_indices as $index) {
  649. if ($index->hasDeletions()) {
  650. return true;
  651. }
  652. }
  653. return false;
  654. }
  655. /**
  656. * Deletes a document from the index.
  657. * $id is an internal document id
  658. *
  659. * @param integer|Zend_Search_Lucene_Search_QueryHit $id
  660. * @throws Zend_Search_Lucene_Exception
  661. */
  662. public function delete($id)
  663. {
  664. foreach ($this->_indices as $index) {
  665. $indexCount = $index->count();
  666. if ($indexCount > $id) {
  667. $index->delete($id);
  668. return;
  669. }
  670. $id -= $indexCount;
  671. }
  672. require_once 'Zend/Search/Lucene/Exception.php';
  673. throw new Zend_Search_Lucene_Exception('Document id is out of the range.');
  674. }
  675. /**
  676. * Callback used to choose target index for new documents
  677. *
  678. * Function/method signature:
  679. * Zend_Search_Lucene_Interface callbackFunction(Zend_Search_Lucene_Document $document, array $indices);
  680. *
  681. * null means "default documents distributing algorithm"
  682. *
  683. * @var callback
  684. */
  685. protected $_documentDistributorCallBack = null;
  686. /**
  687. * Set callback for choosing target index.
  688. *
  689. * @param callback $callback
  690. * @throws Zend_Search_Lucene_Exception
  691. */
  692. public function setDocumentDistributorCallback($callback)
  693. {
  694. if ($callback !== null && !is_callable($callback)) {
  695. require_once 'Zend/Search/Lucene/Exception.php';
  696. throw new Zend_Search_Lucene_Exception('$callback parameter must be a valid callback.');
  697. }
  698. $this->_documentDistributorCallBack = $callback;
  699. }
  700. /**
  701. * Get callback for choosing target index.
  702. *
  703. * @return callback
  704. */
  705. public function getDocumentDistributorCallback()
  706. {
  707. return $this->_documentDistributorCallBack;
  708. }
  709. /**
  710. * Adds a document to this index.
  711. *
  712. * @param Zend_Search_Lucene_Document $document
  713. * @throws Zend_Search_Lucene_Exception
  714. */
  715. public function addDocument(Zend_Search_Lucene_Document $document)
  716. {
  717. if ($this->_documentDistributorCallBack !== null) {
  718. $index = call_user_func($this->_documentDistributorCallBack, $document, $this->_indices);
  719. } else {
  720. $index = $this->_indices[array_rand($this->_indices)];
  721. }
  722. $index->addDocument($document);
  723. }
  724. /**
  725. * Commit changes resulting from delete() or undeleteAll() operations.
  726. */
  727. public function commit()
  728. {
  729. foreach ($this->_indices as $index) {
  730. $index->commit();
  731. }
  732. }
  733. /**
  734. * Optimize index.
  735. *
  736. * Merges all segments into one
  737. */
  738. public function optimize()
  739. {
  740. foreach ($this->_indices as $index) {
  741. $index->optimise();
  742. }
  743. }
  744. /**
  745. * Returns an array of all terms in this index.
  746. *
  747. * @return array
  748. */
  749. public function terms()
  750. {
  751. $termsList = array();
  752. foreach ($this->_indices as $index) {
  753. $termsList[] = $index->terms();
  754. }
  755. return array_unique(call_user_func_array('array_merge', $termsList));
  756. }
  757. /**
  758. * Terms stream priority queue object
  759. *
  760. * @var Zend_Search_Lucene_TermStreamsPriorityQueue
  761. */
  762. private $_termsStream = null;
  763. /**
  764. * Reset terms stream.
  765. */
  766. public function resetTermsStream()
  767. {
  768. if ($this->_termsStream === null) {
  769. /** Zend_Search_Lucene_TermStreamsPriorityQueue */
  770. require_once 'Zend/Search/Lucene/TermStreamsPriorityQueue.php';
  771. $this->_termsStream = new Zend_Search_Lucene_TermStreamsPriorityQueue($this->_indices);
  772. } else {
  773. $this->_termsStream->resetTermsStream();
  774. }
  775. }
  776. /**
  777. * Skip terms stream up to specified term preffix.
  778. *
  779. * Prefix contains fully specified field info and portion of searched term
  780. *
  781. * @param Zend_Search_Lucene_Index_Term $prefix
  782. */
  783. public function skipTo(Zend_Search_Lucene_Index_Term $prefix)
  784. {
  785. $this->_termsStream->skipTo($prefix);
  786. }
  787. /**
  788. * Scans terms dictionary and returns next term
  789. *
  790. * @return Zend_Search_Lucene_Index_Term|null
  791. */
  792. public function nextTerm()
  793. {
  794. return $this->_termsStream->nextTerm();
  795. }
  796. /**
  797. * Returns term in current position
  798. *
  799. * @return Zend_Search_Lucene_Index_Term|null
  800. */
  801. public function currentTerm()
  802. {
  803. return $this->_termsStream->currentTerm();
  804. }
  805. /**
  806. * Close terms stream
  807. *
  808. * Should be used for resources clean up if stream is not read up to the end
  809. */
  810. public function closeTermsStream()
  811. {
  812. $this->_termsStream->closeTermsStream();
  813. $this->_termsStream = null;
  814. }
  815. /**
  816. * Undeletes all documents currently marked as deleted in this index.
  817. */
  818. public function undeleteAll()
  819. {
  820. foreach ($this->_indices as $index) {
  821. $index->undeleteAll();
  822. }
  823. }
  824. /**
  825. * Add reference to the index object
  826. *
  827. * @internal
  828. */
  829. public function addReference()
  830. {
  831. // Do nothing, since it's never referenced by indices
  832. }
  833. /**
  834. * Remove reference from the index object
  835. *
  836. * When reference count becomes zero, index is closed and resources are cleaned up
  837. *
  838. * @internal
  839. */
  840. public function removeReference()
  841. {
  842. // Do nothing, since it's never referenced by indices
  843. }
  844. }