File indexing completed on 2024-05-26 06:03:24

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Search_Lucene
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 
0023 /** Zend_Search_Lucene_Interface */
0024 // require_once 'Zend/Search/Lucene/Interface.php';
0025 
0026 /**
0027  * Import Zend_Search_Lucene_Interface_MultiSearcher for BC (see ZF-12067)
0028  * @see Zend_Search_Lucene_Interface_MultiSearcher 
0029  */
0030 // require_once 'Zend/Search/Lucene/Interface/MultiSearcher.php';
0031 
0032 /**
0033  * Multisearcher allows to search through several independent indexes.
0034  *
0035  * @category   Zend
0036  * @package    Zend_Search_Lucene
0037  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0038  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0039  */
0040 class Zend_Search_Lucene_MultiSearcher implements Zend_Search_Lucene_Interface
0041 {
0042     /**
0043      * List of indices for searching.
0044      * Array of Zend_Search_Lucene_Interface objects
0045      *
0046      * @var array
0047      */
0048     protected $_indices;
0049 
0050     /**
0051      * Object constructor.
0052      *
0053      * @param array $indices   Arrays of indices for search
0054      * @throws Zend_Search_Lucene_Exception
0055      */
0056     public function __construct($indices = array())
0057     {
0058         $this->_indices = $indices;
0059 
0060         foreach ($this->_indices as $index) {
0061             if (!$index instanceof Zend_Search_Lucene_Interface) {
0062                 // require_once 'Zend/Search/Lucene/Exception.php';
0063                 throw new Zend_Search_Lucene_Exception('sub-index objects have to implement Zend_Search_Lucene_Interface.');
0064             }
0065         }
0066     }
0067 
0068     /**
0069      * Add index for searching.
0070      *
0071      * @param Zend_Search_Lucene_Interface $index
0072      */
0073     public function addIndex(Zend_Search_Lucene_Interface $index)
0074     {
0075         $this->_indices[] = $index;
0076     }
0077 
0078 
0079     /**
0080      * Get current generation number
0081      *
0082      * Returns generation number
0083      * 0 means pre-2.1 index format
0084      * -1 means there are no segments files.
0085      *
0086      * @param Zend_Search_Lucene_Storage_Directory $directory
0087      * @return integer
0088      * @throws Zend_Search_Lucene_Exception
0089      */
0090     public static function getActualGeneration(Zend_Search_Lucene_Storage_Directory $directory)
0091     {
0092         // require_once 'Zend/Search/Lucene/Exception.php';
0093         throw new Zend_Search_Lucene_Exception("Generation number can't be retrieved for multi-searcher");
0094     }
0095 
0096     /**
0097      * Get segments file name
0098      *
0099      * @param integer $generation
0100      * @return string
0101      */
0102     public static function getSegmentFileName($generation)
0103     {
0104         return Zend_Search_Lucene::getSegmentFileName($generation);
0105     }
0106 
0107     /**
0108      * Get index format version
0109      *
0110      * @return integer
0111      * @throws Zend_Search_Lucene_Exception
0112      */
0113     public function getFormatVersion()
0114     {
0115         // require_once 'Zend/Search/Lucene/Exception.php';
0116         throw new Zend_Search_Lucene_Exception("Format version can't be retrieved for multi-searcher");
0117     }
0118 
0119     /**
0120      * Set index format version.
0121      * Index is converted to this format at the nearest upfdate time
0122      *
0123      * @param int $formatVersion
0124      */
0125     public function setFormatVersion($formatVersion)
0126     {
0127         foreach ($this->_indices as $index) {
0128             $index->setFormatVersion($formatVersion);
0129         }
0130     }
0131 
0132     /**
0133      * Returns the Zend_Search_Lucene_Storage_Directory instance for this index.
0134      *
0135      * @return Zend_Search_Lucene_Storage_Directory
0136      */
0137     public function getDirectory()
0138     {
0139         // require_once 'Zend/Search/Lucene/Exception.php';
0140         throw new Zend_Search_Lucene_Exception("Index directory can't be retrieved for multi-searcher");
0141     }
0142 
0143     /**
0144      * Returns the total number of documents in this index (including deleted documents).
0145      *
0146      * @return integer
0147      */
0148     public function count()
0149     {
0150         $count = 0;
0151 
0152         foreach ($this->_indices as $index) {
0153             $count += $index->count();
0154         }
0155 
0156         return $count;
0157     }
0158 
0159     /**
0160      * Returns one greater than the largest possible document number.
0161      * This may be used to, e.g., determine how big to allocate a structure which will have
0162      * an element for every document number in an index.
0163      *
0164      * @return integer
0165      */
0166     public function maxDoc()
0167     {
0168         return $this->count();
0169     }
0170 
0171     /**
0172      * Returns the total number of non-deleted documents in this index.
0173      *
0174      * @return integer
0175      */
0176     public function numDocs()
0177     {
0178         $docs = 0;
0179 
0180         foreach ($this->_indices as $index) {
0181             $docs += $index->numDocs();
0182         }
0183 
0184         return $docs;
0185     }
0186 
0187     /**
0188      * Checks, that document is deleted
0189      *
0190      * @param integer $id
0191      * @return boolean
0192      * @throws Zend_Search_Lucene_Exception    Exception is thrown if $id is out of the range
0193      */
0194     public function isDeleted($id)
0195     {
0196         foreach ($this->_indices as $index) {
0197             $indexCount = $index->count();
0198 
0199             if ($indexCount > $id) {
0200                 return $index->isDeleted($id);
0201             }
0202 
0203             $id -= $indexCount;
0204         }
0205 
0206         // require_once 'Zend/Search/Lucene/Exception.php';
0207         throw new Zend_Search_Lucene_Exception('Document id is out of the range.');
0208     }
0209 
0210     /**
0211      * Set default search field.
0212      *
0213      * Null means, that search is performed through all fields by default
0214      *
0215      * Default value is null
0216      *
0217      * @param string $fieldName
0218      */
0219     public static function setDefaultSearchField($fieldName)
0220     {
0221         foreach ($this->_indices as $index) {
0222             $index->setDefaultSearchField($fieldName);
0223         }
0224     }
0225 
0226 
0227     /**
0228      * Get default search field.
0229      *
0230      * Null means, that search is performed through all fields by default
0231      *
0232      * @return string
0233      * @throws Zend_Search_Lucene_Exception
0234      */
0235     public static function getDefaultSearchField()
0236     {
0237         if (count($this->_indices) == 0) {
0238             // require_once 'Zend/Search/Lucene/Exception.php';
0239             throw new Zend_Search_Lucene_Exception('Indices list is empty');
0240         }
0241 
0242         $defaultSearchField = reset($this->_indices)->getDefaultSearchField();
0243 
0244         foreach ($this->_indices as $index) {
0245             if ($index->getDefaultSearchField() !== $defaultSearchField) {
0246                 // require_once 'Zend/Search/Lucene/Exception.php';
0247                 throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
0248             }
0249         }
0250 
0251         return $defaultSearchField;
0252     }
0253 
0254     /**
0255      * Set result set limit.
0256      *
0257      * 0 (default) means no limit
0258      *
0259      * @param integer $limit
0260      */
0261     public static function setResultSetLimit($limit)
0262     {
0263         foreach ($this->_indices as $index) {
0264             $index->setResultSetLimit($limit);
0265         }
0266     }
0267 
0268     /**
0269      * Set result set limit.
0270      *
0271      * 0 means no limit
0272      *
0273      * @return integer
0274      * @throws Zend_Search_Lucene_Exception
0275      */
0276     public static function getResultSetLimit()
0277     {
0278         if (count($this->_indices) == 0) {
0279             // require_once 'Zend/Search/Lucene/Exception.php';
0280             throw new Zend_Search_Lucene_Exception('Indices list is empty');
0281         }
0282 
0283         $defaultResultSetLimit = reset($this->_indices)->getResultSetLimit();
0284 
0285         foreach ($this->_indices as $index) {
0286             if ($index->getResultSetLimit() !== $defaultResultSetLimit) {
0287                 // require_once 'Zend/Search/Lucene/Exception.php';
0288                 throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
0289             }
0290         }
0291 
0292         return $defaultResultSetLimit;
0293     }
0294 
0295     /**
0296      * Retrieve index maxBufferedDocs option
0297      *
0298      * maxBufferedDocs is a minimal number of documents required before
0299      * the buffered in-memory documents are written into a new Segment
0300      *
0301      * Default value is 10
0302      *
0303      * @return integer
0304      * @throws Zend_Search_Lucene_Exception
0305      */
0306     public function getMaxBufferedDocs()
0307     {
0308         if (count($this->_indices) == 0) {
0309             // require_once 'Zend/Search/Lucene/Exception.php';
0310             throw new Zend_Search_Lucene_Exception('Indices list is empty');
0311         }
0312 
0313         $maxBufferedDocs = reset($this->_indices)->getMaxBufferedDocs();
0314 
0315         foreach ($this->_indices as $index) {
0316             if ($index->getMaxBufferedDocs() !== $maxBufferedDocs) {
0317                 // require_once 'Zend/Search/Lucene/Exception.php';
0318                 throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
0319             }
0320         }
0321 
0322         return $maxBufferedDocs;
0323     }
0324 
0325     /**
0326      * Set index maxBufferedDocs option
0327      *
0328      * maxBufferedDocs is a minimal number of documents required before
0329      * the buffered in-memory documents are written into a new Segment
0330      *
0331      * Default value is 10
0332      *
0333      * @param integer $maxBufferedDocs
0334      */
0335     public function setMaxBufferedDocs($maxBufferedDocs)
0336     {
0337         foreach ($this->_indices as $index) {
0338             $index->setMaxBufferedDocs($maxBufferedDocs);
0339         }
0340     }
0341 
0342     /**
0343      * Retrieve index maxMergeDocs option
0344      *
0345      * maxMergeDocs is a largest number of documents ever merged by addDocument().
0346      * Small values (e.g., less than 10,000) are best for interactive indexing,
0347      * as this limits the length of pauses while indexing to a few seconds.
0348      * Larger values are best for batched indexing and speedier searches.
0349      *
0350      * Default value is PHP_INT_MAX
0351      *
0352      * @return integer
0353      * @throws Zend_Search_Lucene_Exception
0354      */
0355     public function getMaxMergeDocs()
0356     {
0357         if (count($this->_indices) == 0) {
0358             // require_once 'Zend/Search/Lucene/Exception.php';
0359             throw new Zend_Search_Lucene_Exception('Indices list is empty');
0360         }
0361 
0362         $maxMergeDocs = reset($this->_indices)->getMaxMergeDocs();
0363 
0364         foreach ($this->_indices as $index) {
0365             if ($index->getMaxMergeDocs() !== $maxMergeDocs) {
0366                 // require_once 'Zend/Search/Lucene/Exception.php';
0367                 throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
0368             }
0369         }
0370 
0371         return $maxMergeDocs;
0372     }
0373 
0374     /**
0375      * Set index maxMergeDocs option
0376      *
0377      * maxMergeDocs is a largest number of documents ever merged by addDocument().
0378      * Small values (e.g., less than 10,000) are best for interactive indexing,
0379      * as this limits the length of pauses while indexing to a few seconds.
0380      * Larger values are best for batched indexing and speedier searches.
0381      *
0382      * Default value is PHP_INT_MAX
0383      *
0384      * @param integer $maxMergeDocs
0385      */
0386     public function setMaxMergeDocs($maxMergeDocs)
0387     {
0388         foreach ($this->_indices as $index) {
0389             $index->setMaxMergeDocs($maxMergeDocs);
0390         }
0391     }
0392 
0393     /**
0394      * Retrieve index mergeFactor option
0395      *
0396      * mergeFactor determines how often segment indices are merged by addDocument().
0397      * With smaller values, less RAM is used while indexing,
0398      * and searches on unoptimized indices are faster,
0399      * but indexing speed is slower.
0400      * With larger values, more RAM is used during indexing,
0401      * and while searches on unoptimized indices are slower,
0402      * indexing is faster.
0403      * Thus larger values (> 10) are best for batch index creation,
0404      * and smaller values (< 10) for indices that are interactively maintained.
0405      *
0406      * Default value is 10
0407      *
0408      * @return integer
0409      * @throws Zend_Search_Lucene_Exception
0410      */
0411     public function getMergeFactor()
0412     {
0413         if (count($this->_indices) == 0) {
0414             // require_once 'Zend/Search/Lucene/Exception.php';
0415             throw new Zend_Search_Lucene_Exception('Indices list is empty');
0416         }
0417 
0418         $mergeFactor = reset($this->_indices)->getMergeFactor();
0419 
0420         foreach ($this->_indices as $index) {
0421             if ($index->getMergeFactor() !== $mergeFactor) {
0422                 // require_once 'Zend/Search/Lucene/Exception.php';
0423                 throw new Zend_Search_Lucene_Exception('Indices have different default search field.');
0424             }
0425         }
0426 
0427         return $mergeFactor;
0428     }
0429 
0430     /**
0431      * Set index mergeFactor option
0432      *
0433      * mergeFactor determines how often segment indices are merged by addDocument().
0434      * With smaller values, less RAM is used while indexing,
0435      * and searches on unoptimized indices are faster,
0436      * but indexing speed is slower.
0437      * With larger values, more RAM is used during indexing,
0438      * and while searches on unoptimized indices are slower,
0439      * indexing is faster.
0440      * Thus larger values (> 10) are best for batch index creation,
0441      * and smaller values (< 10) for indices that are interactively maintained.
0442      *
0443      * Default value is 10
0444      *
0445      * @param integer $maxMergeDocs
0446      */
0447     public function setMergeFactor($mergeFactor)
0448     {
0449         foreach ($this->_indices as $index) {
0450             $index->setMaxMergeDocs($mergeFactor);
0451         }
0452     }
0453 
0454     /**
0455      * Performs a query against the index and returns an array
0456      * of Zend_Search_Lucene_Search_QueryHit objects.
0457      * Input is a string or Zend_Search_Lucene_Search_Query.
0458      *
0459      * @param mixed $query
0460      * @return array Zend_Search_Lucene_Search_QueryHit
0461      * @throws Zend_Search_Lucene_Exception
0462      */
0463     public function find($query)
0464     {
0465         if (count($this->_indices) == 0) {
0466             return array();
0467         }
0468 
0469         $hitsList = array();
0470 
0471         $indexShift = 0;
0472         foreach ($this->_indices as $index) {
0473             $hits = $index->find($query);
0474 
0475             if ($indexShift != 0) {
0476                 foreach ($hits as $hit) {
0477                     $hit->id += $indexShift;
0478                 }
0479             }
0480 
0481             $indexShift += $index->count();
0482             $hitsList[] = $hits;
0483         }
0484 
0485         /** @todo Implement advanced sorting */
0486 
0487         return call_user_func_array('array_merge', $hitsList);
0488     }
0489 
0490     /**
0491      * Returns a list of all unique field names that exist in this index.
0492      *
0493      * @param boolean $indexed
0494      * @return array
0495      */
0496     public function getFieldNames($indexed = false)
0497     {
0498         $fieldNamesList = array();
0499 
0500         foreach ($this->_indices as $index) {
0501             $fieldNamesList[] = $index->getFieldNames($indexed);
0502         }
0503 
0504         return array_unique(call_user_func_array('array_merge', $fieldNamesList));
0505     }
0506 
0507     /**
0508      * Returns a Zend_Search_Lucene_Document object for the document
0509      * number $id in this index.
0510      *
0511      * @param integer|Zend_Search_Lucene_Search_QueryHit $id
0512      * @return Zend_Search_Lucene_Document
0513      * @throws Zend_Search_Lucene_Exception    Exception is thrown if $id is out of the range
0514      */
0515     public function getDocument($id)
0516     {
0517         if ($id instanceof Zend_Search_Lucene_Search_QueryHit) {
0518             /* @var $id Zend_Search_Lucene_Search_QueryHit */
0519             $id = $id->id;
0520         }
0521 
0522         foreach ($this->_indices as $index) {
0523             $indexCount = $index->count();
0524 
0525             if ($indexCount > $id) {
0526                 return $index->getDocument($id);
0527             }
0528 
0529             $id -= $indexCount;
0530         }
0531 
0532         // require_once 'Zend/Search/Lucene/Exception.php';
0533         throw new Zend_Search_Lucene_Exception('Document id is out of the range.');
0534     }
0535 
0536     /**
0537      * Returns true if index contain documents with specified term.
0538      *
0539      * Is used for query optimization.
0540      *
0541      * @param Zend_Search_Lucene_Index_Term $term
0542      * @return boolean
0543      */
0544     public function hasTerm(Zend_Search_Lucene_Index_Term $term)
0545     {
0546         foreach ($this->_indices as $index) {
0547             if ($index->hasTerm($term)) {
0548                 return true;
0549             }
0550         }
0551 
0552         return false;
0553     }
0554 
0555     /**
0556      * Returns IDs of all the documents containing term.
0557      *
0558      * @param Zend_Search_Lucene_Index_Term $term
0559      * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
0560      * @return array
0561      * @throws Zend_Search_Lucene_Exception
0562      */
0563     public function termDocs(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
0564     {
0565         if ($docsFilter != null) {
0566             // require_once 'Zend/Search/Lucene/Exception.php';
0567             throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
0568         }
0569 
0570         $docsList = array();
0571 
0572         $indexShift = 0;
0573         foreach ($this->_indices as $index) {
0574             $docs = $index->termDocs($term);
0575 
0576             if ($indexShift != 0) {
0577                 foreach ($docs as $id => $docId) {
0578                     $docs[$id] += $indexShift;
0579                 }
0580             }
0581 
0582             $indexShift += $index->count();
0583             $docsList[] = $docs;
0584         }
0585 
0586         return call_user_func_array('array_merge', $docsList);
0587     }
0588 
0589     /**
0590      * Returns documents filter for all documents containing term.
0591      *
0592      * It performs the same operation as termDocs, but return result as
0593      * Zend_Search_Lucene_Index_DocsFilter object
0594      *
0595      * @param Zend_Search_Lucene_Index_Term $term
0596      * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
0597      * @return Zend_Search_Lucene_Index_DocsFilter
0598      * @throws Zend_Search_Lucene_Exception
0599      */
0600     public function termDocsFilter(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
0601     {
0602         // require_once 'Zend/Search/Lucene/Exception.php';
0603         throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
0604     }
0605 
0606     /**
0607      * Returns an array of all term freqs.
0608      * Return array structure: array( docId => freq, ...)
0609      *
0610      * @param Zend_Search_Lucene_Index_Term $term
0611      * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
0612      * @return integer
0613      * @throws Zend_Search_Lucene_Exception
0614      */
0615     public function termFreqs(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
0616     {
0617         if ($docsFilter != null) {
0618             // require_once 'Zend/Search/Lucene/Exception.php';
0619             throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
0620         }
0621 
0622         $freqsList = array();
0623 
0624         $indexShift = 0;
0625         foreach ($this->_indices as $index) {
0626             $freqs = $index->termFreqs($term);
0627 
0628             if ($indexShift != 0) {
0629                 $freqsShifted = array();
0630 
0631                 foreach ($freqs as $docId => $freq) {
0632                     $freqsShifted[$docId + $indexShift] = $freq;
0633                 }
0634                 $freqs = $freqsShifted;
0635             }
0636 
0637             $indexShift += $index->count();
0638             $freqsList[] = $freqs;
0639         }
0640 
0641         return call_user_func_array('array_merge', $freqsList);
0642     }
0643 
0644     /**
0645      * Returns an array of all term positions in the documents.
0646      * Return array structure: array( docId => array( pos1, pos2, ...), ...)
0647      *
0648      * @param Zend_Search_Lucene_Index_Term $term
0649      * @param Zend_Search_Lucene_Index_DocsFilter|null $docsFilter
0650      * @return array
0651      * @throws Zend_Search_Lucene_Exception
0652      */
0653     public function termPositions(Zend_Search_Lucene_Index_Term $term, $docsFilter = null)
0654     {
0655         if ($docsFilter != null) {
0656             // require_once 'Zend/Search/Lucene/Exception.php';
0657             throw new Zend_Search_Lucene_Exception('Document filters could not used with multi-searcher');
0658         }
0659 
0660         $termPositionsList = array();
0661 
0662         $indexShift = 0;
0663         foreach ($this->_indices as $index) {
0664             $termPositions = $index->termPositions($term);
0665 
0666             if ($indexShift != 0) {
0667                 $termPositionsShifted = array();
0668 
0669                 foreach ($termPositions as $docId => $positions) {
0670                     $termPositions[$docId + $indexShift] = $positions;
0671                 }
0672                 $termPositions = $termPositionsShifted;
0673             }
0674 
0675             $indexShift += $index->count();
0676             $termPositionsList[] = $termPositions;
0677         }
0678 
0679         return call_user_func_array('array_merge', $termPositions);
0680     }
0681 
0682     /**
0683      * Returns the number of documents in this index containing the $term.
0684      *
0685      * @param Zend_Search_Lucene_Index_Term $term
0686      * @return integer
0687      */
0688     public function docFreq(Zend_Search_Lucene_Index_Term $term)
0689     {
0690         $docFreq = 0;
0691 
0692         foreach ($this->_indices as $index) {
0693             $docFreq += $index->docFreq($term);
0694         }
0695 
0696         return $docFreq;
0697     }
0698 
0699     /**
0700      * Retrive similarity used by index reader
0701      *
0702      * @return Zend_Search_Lucene_Search_Similarity
0703      * @throws Zend_Search_Lucene_Exception
0704      */
0705     public function getSimilarity()
0706     {
0707         if (count($this->_indices) == 0) {
0708             // require_once 'Zend/Search/Lucene/Exception.php';
0709             throw new Zend_Search_Lucene_Exception('Indices list is empty');
0710         }
0711 
0712         $similarity = reset($this->_indices)->getSimilarity();
0713 
0714         foreach ($this->_indices as $index) {
0715             if ($index->getSimilarity() !== $similarity) {
0716                 // require_once 'Zend/Search/Lucene/Exception.php';
0717                 throw new Zend_Search_Lucene_Exception('Indices have different similarity.');
0718             }
0719         }
0720 
0721         return $similarity;
0722     }
0723 
0724     /**
0725      * Returns a normalization factor for "field, document" pair.
0726      *
0727      * @param integer $id
0728      * @param string $fieldName
0729      * @return float
0730      */
0731     public function norm($id, $fieldName)
0732     {
0733         foreach ($this->_indices as $index) {
0734             $indexCount = $index->count();
0735 
0736             if ($indexCount > $id) {
0737                 return $index->norm($id, $fieldName);
0738             }
0739 
0740             $id -= $indexCount;
0741         }
0742 
0743         return null;
0744     }
0745 
0746     /**
0747      * Returns true if any documents have been deleted from this index.
0748      *
0749      * @return boolean
0750      */
0751     public function hasDeletions()
0752     {
0753         foreach ($this->_indices as $index) {
0754             if ($index->hasDeletions()) {
0755                 return true;
0756             }
0757         }
0758 
0759         return false;
0760     }
0761 
0762     /**
0763      * Deletes a document from the index.
0764      * $id is an internal document id
0765      *
0766      * @param integer|Zend_Search_Lucene_Search_QueryHit $id
0767      * @throws Zend_Search_Lucene_Exception
0768      */
0769     public function delete($id)
0770     {
0771         foreach ($this->_indices as $index) {
0772             $indexCount = $index->count();
0773 
0774             if ($indexCount > $id) {
0775                 $index->delete($id);
0776                 return;
0777             }
0778 
0779             $id -= $indexCount;
0780         }
0781 
0782         // require_once 'Zend/Search/Lucene/Exception.php';
0783         throw new Zend_Search_Lucene_Exception('Document id is out of the range.');
0784     }
0785 
0786 
0787     /**
0788      * Callback used to choose target index for new documents
0789      *
0790      * Function/method signature:
0791      *    Zend_Search_Lucene_Interface  callbackFunction(Zend_Search_Lucene_Document $document, array $indices);
0792      *
0793      * null means "default documents distributing algorithm"
0794      *
0795      * @var callback
0796      */
0797     protected $_documentDistributorCallBack = null;
0798 
0799     /**
0800      * Set callback for choosing target index.
0801      *
0802      * @param callback $callback
0803      * @throws Zend_Search_Lucene_Exception
0804      */
0805     public function setDocumentDistributorCallback($callback)
0806     {
0807         if ($callback !== null  &&  !is_callable($callback)) {
0808             // require_once 'Zend/Search/Lucene/Exception.php';
0809             throw new Zend_Search_Lucene_Exception('$callback parameter must be a valid callback.');
0810         }
0811 
0812         $this->_documentDistributorCallBack = $callback;
0813     }
0814 
0815     /**
0816      * Get callback for choosing target index.
0817      *
0818      * @return callback
0819      */
0820     public function getDocumentDistributorCallback()
0821     {
0822         return $this->_documentDistributorCallBack;
0823     }
0824 
0825     /**
0826      * Adds a document to this index.
0827      *
0828      * @param Zend_Search_Lucene_Document $document
0829      * @throws Zend_Search_Lucene_Exception
0830      */
0831     public function addDocument(Zend_Search_Lucene_Document $document)
0832     {
0833         if ($this->_documentDistributorCallBack !== null) {
0834             $index = call_user_func($this->_documentDistributorCallBack, $document, $this->_indices);
0835         } else {
0836             $index = $this->_indices[array_rand($this->_indices)];
0837         }
0838 
0839         $index->addDocument($document);
0840     }
0841 
0842     /**
0843      * Commit changes resulting from delete() or undeleteAll() operations.
0844      */
0845     public function commit()
0846     {
0847         foreach ($this->_indices as $index) {
0848             $index->commit();
0849         }
0850     }
0851 
0852     /**
0853      * Optimize index.
0854      *
0855      * Merges all segments into one
0856      */
0857     public function optimize()
0858     {
0859         foreach ($this->_indices as $index) {
0860             $index->optimise();
0861         }
0862     }
0863 
0864     /**
0865      * Returns an array of all terms in this index.
0866      *
0867      * @return array
0868      */
0869     public function terms()
0870     {
0871         $termsList = array();
0872 
0873         foreach ($this->_indices as $index) {
0874             $termsList[] = $index->terms();
0875         }
0876 
0877         return array_unique(call_user_func_array('array_merge', $termsList));
0878     }
0879 
0880 
0881     /**
0882      * Terms stream priority queue object
0883      *
0884      * @var Zend_Search_Lucene_TermStreamsPriorityQueue
0885      */
0886     private $_termsStream = null;
0887 
0888     /**
0889      * Reset terms stream.
0890      */
0891     public function resetTermsStream()
0892     {
0893         if ($this->_termsStream === null) {
0894             /** Zend_Search_Lucene_TermStreamsPriorityQueue */
0895             // require_once 'Zend/Search/Lucene/TermStreamsPriorityQueue.php';
0896 
0897             $this->_termsStream = new Zend_Search_Lucene_TermStreamsPriorityQueue($this->_indices);
0898         } else {
0899             $this->_termsStream->resetTermsStream();
0900         }
0901     }
0902 
0903     /**
0904      * Skip terms stream up to specified term preffix.
0905      *
0906      * Prefix contains fully specified field info and portion of searched term
0907      *
0908      * @param Zend_Search_Lucene_Index_Term $prefix
0909      */
0910     public function skipTo(Zend_Search_Lucene_Index_Term $prefix)
0911     {
0912         $this->_termsStream->skipTo($prefix);
0913     }
0914 
0915     /**
0916      * Scans terms dictionary and returns next term
0917      *
0918      * @return Zend_Search_Lucene_Index_Term|null
0919      */
0920     public function nextTerm()
0921     {
0922         return $this->_termsStream->nextTerm();
0923     }
0924 
0925     /**
0926      * Returns term in current position
0927      *
0928      * @return Zend_Search_Lucene_Index_Term|null
0929      */
0930     public function currentTerm()
0931     {
0932         return $this->_termsStream->currentTerm();
0933     }
0934 
0935     /**
0936      * Close terms stream
0937      *
0938      * Should be used for resources clean up if stream is not read up to the end
0939      */
0940     public function closeTermsStream()
0941     {
0942         $this->_termsStream->closeTermsStream();
0943         $this->_termsStream = null;
0944     }
0945 
0946 
0947     /**
0948      * Undeletes all documents currently marked as deleted in this index.
0949      */
0950     public function undeleteAll()
0951     {
0952         foreach ($this->_indices as $index) {
0953             $index->undeleteAll();
0954         }
0955     }
0956 
0957 
0958     /**
0959      * Add reference to the index object
0960      *
0961      * @internal
0962      */
0963     public function addReference()
0964     {
0965         // Do nothing, since it's never referenced by indices
0966     }
0967 
0968     /**
0969      * Remove reference from the index object
0970      *
0971      * When reference count becomes zero, index is closed and resources are cleaned up
0972      *
0973      * @internal
0974      */
0975     public function removeReference()
0976     {
0977         // Do nothing, since it's never referenced by indices
0978     }
0979 }
0980 
0981 /**
0982  * This class is provided for backwards-compatibility (See ZF-12067)
0983  *
0984  * @category   Zend
0985  * @package    Zend_Search_Lucene
0986  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0987  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0988  */
0989 class Zend_Search_Lucene_Interface_MultiSearcher
0990     extends Zend_Search_Lucene_MultiSearcher
0991 {
0992 }