| [ Index ] |
|
Code source de PRADO 3.0.6 |
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to version 1.0 of the Zend Framework 8 * license, that is bundled with this package in the file LICENSE, and 9 * is available through the world-wide-web at the following URL: 10 * http://www.zend.com/license/framework/1_0.txt. If you did not receive 11 * a copy of the Zend Framework license and are unable to obtain it 12 * through the world-wide-web, please send a note to license@zend.com 13 * so we can mail you a copy immediately. 14 * 15 * @package Zend_Search_Lucene 16 * @copyright Copyright (c) 2005-2006 Zend Technologies USA Inc. (http://www.zend.com) 17 * @license http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0 18 */ 19 20 21 /** Zend_Search_Lucene_Exception */ 22 require_once 'Zend/Search/Lucene/Exception.php'; 23 24 /** Zend_Search_Lucene_Document */ 25 require_once 'Zend/Search/Lucene/Document.php'; 26 27 /** Zend_Search_Lucene_Storage_Directory */ 28 require_once 'Zend/Search/Lucene/Storage/Directory/Filesystem.php'; 29 30 /** Zend_Search_Lucene_Index_Term */ 31 require_once 'Zend/Search/Lucene/Index/Term.php'; 32 33 /** Zend_Search_Lucene_Index_TermInfo */ 34 require_once 'Zend/Search/Lucene/Index/TermInfo.php'; 35 36 /** Zend_Search_Lucene_Index_SegmentInfo */ 37 require_once 'Zend/Search/Lucene/Index/SegmentInfo.php'; 38 39 /** Zend_Search_Lucene_Index_FieldInfo */ 40 require_once 'Zend/Search/Lucene/Index/FieldInfo.php'; 41 42 /** Zend_Search_Lucene_Index_Writer */ 43 require_once 'Zend/Search/Lucene/Index/Writer.php'; 44 45 /** Zend_Search_Lucene_Search_QueryParser */ 46 require_once 'Zend/Search/Lucene/Search/QueryParser.php'; 47 48 /** Zend_Search_Lucene_Search_QueryHit */ 49 require_once 'Zend/Search/Lucene/Search/QueryHit.php'; 50 51 /** Zend_Search_Lucene_Search_Similarity */ 52 require_once 'Zend/Search/Lucene/Search/Similarity.php'; 53 54 55 /** 56 * @package Zend_Search_Lucene 57 * @copyright Copyright (c) 2005-2006 Zend Technologies USA Inc. (http://www.zend.com) 58 * @license http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0 59 */ 60 class Zend_Search_Lucene 61 { 62 /** 63 * File system adapter. 64 * 65 * @var Zend_Search_Lucene_Storage_Directory 66 */ 67 private $_directory = null; 68 69 /** 70 * File system adapter closing option 71 * 72 * @var boolean 73 */ 74 private $_closeDirOnExit = true; 75 76 /** 77 * Writer for this index, not instantiated unless required. 78 * 79 * @var Zend_Search_Lucene_Index_Writer 80 */ 81 private $_writer = null; 82 83 /** 84 * Array of Zend_Search_Lucene_Index_SegmentInfo objects for this index. 85 * 86 * @var array Zend_Search_Lucene_Index_SegmentInfo 87 */ 88 private $_segmentInfos = array(); 89 90 /** 91 * Number of documents in this index. 92 * 93 * @var integer 94 */ 95 private $_docCount = 0; 96 97 98 /** 99 * Opens the index. 100 * 101 * IndexReader constructor needs Directory as a parameter. It should be 102 * a string with a path to the index folder or a Directory object. 103 * 104 * @param mixed $directory 105 * @throws Zend_Search_Lucene_Exception 106 */ 107 public function __construct($directory = null, $create = false) 108 { 109 if ($directory === null) { 110 throw new Zend_Search_Exception('No index directory specified'); 111 } 112 113 if ($directory instanceof Zend_Search_Lucene_Storage_Directory_Filesystem) { 114 $this->_directory = $directory; 115 $this->_closeDirOnExit = false; 116 } else { 117 $this->_directory = new Zend_Search_Lucene_Storage_Directory_Filesystem($directory); 118 $this->_closeDirOnExit = true; 119 } 120 121 if ($create) { 122 $this->_writer = new Zend_Search_Lucene_Index_Writer($this->_directory, true); 123 } else { 124 $this->_writer = null; 125 } 126 127 $this->_segmentInfos = array(); 128 129 $segmentsFile = $this->_directory->getFileObject('segments'); 130 131 $format = $segmentsFile->readInt(); 132 133 if ($format != (int)0xFFFFFFFF) { 134 throw new Zend_Search_Lucene_Exception('Wrong segments file format'); 135 } 136 137 // read version 138 $segmentsFile->readLong(); 139 140 // read counter 141 $segmentsFile->readInt(); 142 143 $segments = $segmentsFile->readInt(); 144 145 $this->_docCount = 0; 146 147 // read segmentInfos 148 for ($count = 0; $count < $segments; $count++) { 149 $segName = $segmentsFile->readString(); 150 $segSize = $segmentsFile->readInt(); 151 $this->_docCount += $segSize; 152 153 $this->_segmentInfos[$count] = 154 new Zend_Search_Lucene_Index_SegmentInfo($segName, 155 $segSize, 156 $this->_directory); 157 } 158 } 159 160 161 /** 162 * Object destructor 163 */ 164 public function __destruct() 165 { 166 $this->commit(); 167 168 if ($this->_closeDirOnExit) { 169 $this->_directory->close(); 170 } 171 } 172 173 /** 174 * Returns an instance of Zend_Search_Lucene_Index_Writer for the index 175 * 176 * @return Zend_Search_Lucene_Index_Writer 177 */ 178 public function getIndexWriter() 179 { 180 if (!$this->_writer instanceof Zend_Search_Lucene_Index_Writer) { 181 $this->_writer = new Zend_Search_Lucene_Index_Writer($this->_directory); 182 } 183 184 return $this->_writer; 185 } 186 187 188 /** 189 * Returns the Zend_Search_Lucene_Storage_Directory instance for this index. 190 * 191 * @return Zend_Search_Lucene_Storage_Directory 192 */ 193 public function getDirectory() 194 { 195 return $this->_directory; 196 } 197 198 199 /** 200 * Returns the total number of documents in this index. 201 * 202 * @return integer 203 */ 204 public function count() 205 { 206 return $this->_docCount; 207 } 208 209 210 /** 211 * Performs a query against the index and returns an array 212 * of Zend_Search_Lucene_Search_QueryHit objects. 213 * Input is a string or Zend_Search_Lucene_Search_Query. 214 * 215 * @param mixed $query 216 * @return array ZSearchHit 217 */ 218 public function find($query) 219 { 220 if (is_string($query)) { 221 $query = Zend_Search_Lucene_Search_QueryParser::parse($query); 222 } 223 224 if (!$query instanceof Zend_Search_Lucene_Search_Query) { 225 throw new Zend_Search_Lucene_Exception('Query must be a string or Zend_Search_Lucene_Search_Query object'); 226 } 227 228 $this->commit(); 229 230 $hits = array(); 231 $scores = array(); 232 233 $docNum = $this->count(); 234 for( $count=0; $count < $docNum; $count++ ) { 235 $docScore = $query->score( $count, $this); 236 if( $docScore != 0 ) { 237 $hit = new Zend_Search_Lucene_Search_QueryHit($this); 238 $hit->id = $count; 239 $hit->score = $docScore; 240 241 $hits[] = $hit; 242 $scores[] = $docScore; 243 } 244 } 245 array_multisort($scores, SORT_DESC, SORT_REGULAR, $hits); 246 247 return $hits; 248 } 249 250 251 /** 252 * Returns a list of all unique field names that exist in this index. 253 * 254 * @param boolean $indexed 255 * @return array 256 */ 257 public function getFieldNames($indexed = false) 258 { 259 $result = array(); 260 foreach( $this->_segmentInfos as $segmentInfo ) { 261 $result = array_merge($result, $segmentInfo->getFields($indexed)); 262 } 263 return $result; 264 } 265 266 267 /** 268 * Returns a Zend_Search_Lucene_Document object for the document 269 * number $id in this index. 270 * 271 * @param integer|Zend_Search_Lucene_Search_QueryHit $id 272 * @return Zend_Search_Lucene_Document 273 */ 274 public function getDocument($id) 275 { 276 if ($id instanceof Zend_Search_Lucene_Search_QueryHit) { 277 /* @var $id Zend_Search_Lucene_Search_QueryHit */ 278 $id = $id->id; 279 } 280 281 if ($id >= $this->_docCount) { 282 /** 283 * @todo exception here? 284 */ 285 return null; 286 } 287 288 $segCount = 0; 289 $nextSegmentStartId = $this->_segmentInfos[ 0 ]->count(); 290 while( $nextSegmentStartId <= $id ) { 291 $segCount++; 292 $nextSegmentStartId += $this->_segmentInfos[ $segCount ]->count(); 293 } 294 $segmentStartId = $nextSegmentStartId - $this->_segmentInfos[ $segCount ]->count(); 295 296 $fdxFile = $this->_segmentInfos[ $segCount ]->openCompoundFile('.fdx'); 297 $fdxFile->seek( ($id-$segmentStartId)*8, SEEK_CUR ); 298 $fieldValuesPosition = $fdxFile->readLong(); 299 300 $fdtFile = $this->_segmentInfos[ $segCount ]->openCompoundFile('.fdt'); 301 $fdtFile->seek( $fieldValuesPosition, SEEK_CUR ); 302 $fieldCount = $fdtFile->readVInt(); 303 304 $doc = new Zend_Search_Lucene_Document(); 305 for( $count = 0; $count < $fieldCount; $count++ ) { 306 $fieldNum = $fdtFile->readVInt(); 307 $bits = $fdtFile->readByte(); 308 309 $fieldInfo = $this->_segmentInfos[ $segCount ]->getField($fieldNum); 310 311 if( !($bits & 2) ) { // Text data 312 $field = new Zend_Search_Lucene_Field($fieldInfo->name, 313 $fdtFile->readString(), 314 true, 315 $fieldInfo->isIndexed, 316 $bits & 1 ); 317 } else { 318 $field = new Zend_Search_Lucene_Field($fieldInfo->name, 319 $fdtFile->readBinary(), 320 true, 321 $fieldInfo->isIndexed, 322 $bits & 1 ); 323 } 324 325 $doc->addField($field); 326 } 327 328 return $doc; 329 } 330 331 332 /** 333 * Returns an array of all the documents which contain term. 334 * 335 * @param Zend_Search_Lucene_Index_Term $term 336 * @return array 337 */ 338 public function termDocs(Zend_Search_Lucene_Index_Term $term) 339 { 340 $result = array(); 341 $segmentStartDocId = 0; 342 343 foreach ($this->_segmentInfos as $segInfo) { 344 $termInfo = $segInfo->getTermInfo($term); 345 346 if (!$termInfo instanceof Zend_Search_Lucene_Index_TermInfo) { 347 $segmentStartDocId += $segInfo->count(); 348 continue; 349 } 350 351 $frqFile = $segInfo->openCompoundFile('.frq'); 352 $frqFile->seek($termInfo->freqPointer,SEEK_CUR); 353 $docId = 0; 354 for( $count=0; $count < $termInfo->docFreq; $count++ ) { 355 $docDelta = $frqFile->readVInt(); 356 if( $docDelta % 2 == 1 ) { 357 $docId += ($docDelta-1)/2; 358 } else { 359 $docId += $docDelta/2; 360 // read freq 361 $frqFile->readVInt(); 362 } 363 $result[] = $segmentStartDocId + $docId; 364 } 365 366 $segmentStartDocId += $segInfo->count(); 367 } 368 369 return $result; 370 } 371 372 373 /** 374 * Returns an array of all term positions in the documents. 375 * Return array structure: array( docId => array( pos1, pos2, ...), ...) 376 * 377 * @param Zend_Search_Lucene_Index_Term $term 378 * @return array 379 */ 380 public function termPositions(Zend_Search_Lucene_Index_Term $term) 381 { 382 $result = array(); 383 $segmentStartDocId = 0; 384 foreach( $this->_segmentInfos as $segInfo ) { 385 $termInfo = $segInfo->getTermInfo($term); 386 387 if (!$termInfo instanceof Zend_Search_Lucene_Index_TermInfo) { 388 $segmentStartDocId += $segInfo->count(); 389 continue; 390 } 391 392 $frqFile = $segInfo->openCompoundFile('.frq'); 393 $frqFile->seek($termInfo->freqPointer,SEEK_CUR); 394 $freqs = array(); 395 $docId = 0; 396 397 for( $count = 0; $count < $termInfo->docFreq; $count++ ) { 398 $docDelta = $frqFile->readVInt(); 399 if( $docDelta % 2 == 1 ) { 400 $docId += ($docDelta-1)/2; 401 $freqs[ $docId ] = 1; 402 } else { 403 $docId += $docDelta/2; 404 $freqs[ $docId ] = $frqFile->readVInt(); 405 } 406 } 407 408 $prxFile = $segInfo->openCompoundFile('.prx'); 409 $prxFile->seek($termInfo->proxPointer,SEEK_CUR); 410 foreach ($freqs as $docId => $freq) { 411 $termPosition = 0; 412 $positions = array(); 413 414 for ($count = 0; $count < $freq; $count++ ) { 415 $termPosition += $prxFile->readVInt(); 416 $positions[] = $termPosition; 417 } 418 $result[ $segmentStartDocId + $docId ] = $positions; 419 } 420 421 $segmentStartDocId += $segInfo->count(); 422 } 423 424 return $result; 425 } 426 427 428 /** 429 * Returns the number of documents in this index containing the $term. 430 * 431 * @param Zend_Search_Lucene_Index_Term $term 432 * @return integer 433 */ 434 public function docFreq(Zend_Search_Lucene_Index_Term $term) 435 { 436 $result = 0; 437 foreach ($this->_segmentInfos as $segInfo) { 438 $termInfo = $segInfo->getTermInfo($term); 439 if ($termInfo !== null) { 440 $result += $termInfo->docFreq; 441 } 442 } 443 444 return $result; 445 } 446 447 448 /** 449 * Retrive similarity used by index reader 450 * 451 * @return Zend_Search_Lucene_Search_Similarity 452 */ 453 public function getSimilarity() 454 { 455 return Zend_Search_Lucene_Search_Similarity::getDefault(); 456 } 457 458 459 /** 460 * Returns a normalization factor for "field, document" pair. 461 * 462 * @param integer $id 463 * @param string $fieldName 464 * @return Zend_Search_Lucene_Document 465 */ 466 public function norm( $id, $fieldName ) 467 { 468 if( $id >= $this->_docCount ) 469 return null; 470 471 $segCount = 0; 472 $nextSegmentStartId = $this->_segmentInfos[ 0 ]->count(); 473 while( $nextSegmentStartId <= $id ) { 474 $segCount++; 475 $nextSegmentStartId += $this->_segmentInfos[ $segCount ]->count(); 476 } 477 478 $segmentStartId = $nextSegmentStartId - $this->_segmentInfos[ $segCount ]->count(); 479 480 return $this->_segmentInfos[ $segCount ]->norm($id - $segmentStartId, $fieldName); 481 } 482 483 484 /** 485 * Adds a document to this index. 486 * 487 * @param Zend_Search_Lucene_Document $document 488 */ 489 public function addDocument(Zend_Search_Lucene_Document $document) 490 { 491 if (!$this->_writer instanceof Zend_Search_Lucene_Index_Writer) { 492 $this->_writer = new Zend_Search_Lucene_Index_Writer($this->_directory); 493 } 494 495 $this->_writer->addDocument($document); 496 } 497 498 499 /** 500 * Commit changes resulting from delete() or undeleteAll() operations. 501 * 502 * @todo delete() and undeleteAll processing. 503 */ 504 public function commit() 505 { 506 if ($this->_writer !== null) { 507 foreach ($this->_writer->commit() as $segmentName => $segmentInfo) { 508 if ($segmentInfo !== null) { 509 $this->_segmentInfos[] = $segmentInfo; 510 $this->_docCount += $segmentInfo->count(); 511 } else { 512 foreach ($this->_segmentInfos as $segId => $segInfo) { 513 if ($segInfo->getName() == $segmentName) { 514 unset($this->_segmentInfos[$segId]); 515 } 516 } 517 } 518 } 519 } 520 } 521 522 523 /************************************************************************* 524 @todo UNIMPLEMENTED 525 *************************************************************************/ 526 527 /** 528 * Returns an array of all terms in this index. 529 * 530 * @todo Implementation 531 * @return array 532 */ 533 public function terms() 534 { 535 return array(); 536 } 537 538 539 /** 540 * Returns true if any documents have been deleted from this index. 541 * 542 * @todo Implementation 543 * @return boolean 544 */ 545 public function hasDeletions() 546 { 547 return false; 548 } 549 550 551 /** 552 * Deletes a document from the index. $doc may contain a Zend_Search_Lucene_Document 553 * or the number of the document to delete. 554 * 555 * @todo Implementation 556 * @param mixed $item_to_del 557 */ 558 public function delete($doc) 559 {} 560 561 562 /** 563 * Undeletes all documents currently marked as deleted in this index. 564 * 565 * @todo Implementation 566 */ 567 public function undeleteAll() 568 {} 569 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |