📄 multiterm.php
字号:
<?php/** * Zend Framework * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://framework.zend.com/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@zend.com so we can send you a copy immediately. * * @category Zend * @package Zend_Search_Lucene * @subpackage Search * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License *//** Zend_Search_Lucene_Search_Query */require_once 'Zend/Search/Lucene/Search/Query.php';/** Zend_Search_Lucene_Search_Weight_MultiTerm */require_once 'Zend/Search/Lucene/Search/Weight/MultiTerm.php';/** * @category Zend * @package Zend_Search_Lucene * @subpackage Search * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */class Zend_Search_Lucene_Search_Query_MultiTerm extends Zend_Search_Lucene_Search_Query{ /** * Terms to find. * Array of Zend_Search_Lucene_Index_Term * * @var array */ private $_terms = array(); /** * Term signs. * If true then term is required. * If false then term is prohibited. * If null then term is neither prohibited, nor required * * If array is null then all terms are required * * @var array */ private $_signs; /** * Result vector. * * @var array */ private $_resVector = null; /** * Terms positions vectors. * Array of Arrays: * term1Id => (docId => freq, ...) * term2Id => (docId => freq, ...) * * @var array */ private $_termsFreqs = array(); /** * A score factor based on the fraction of all query terms * that a document contains. * float for conjunction queries * array of float for non conjunction queries * * @var mixed */ private $_coord = null; /** * Terms weights * array of Zend_Search_Lucene_Search_Weight * * @var array */ private $_weights = array(); /** * Class constructor. Create a new multi-term query object. * * if $signs array is omitted then all terms are required * it differs from addTerm() behavior, but should never be used * * @param array $terms Array of Zend_Search_Lucene_Index_Term objects * @param array $signs Array of signs. Sign is boolean|null. */ public function __construct($terms = null, $signs = null) { if (is_array($terms)) { $this->_terms = $terms; $this->_signs = null; // Check if all terms are required if (is_array($signs)) { foreach ($signs as $sign ) { if ($sign !== true) { $this->_signs = $signs; break; } } } } } /** * Add a $term (Zend_Search_Lucene_Index_Term) to this query. * * The sign is specified as: * TRUE - term is required * FALSE - term is prohibited * NULL - term is neither prohibited, nor required * * @param Zend_Search_Lucene_Index_Term $term * @param boolean|null $sign * @return void */ public function addTerm(Zend_Search_Lucene_Index_Term $term, $sign = null) { if ($sign !== true || $this->_signs !== null) { // Skip, if all terms are required if ($this->_signs === null) { // Check, If all previous terms are required $this->_signs = array(); foreach ($this->_terms as $prevTerm) { $this->_signs[] = true; } } $this->_signs[] = $sign; } $this->_terms[] = $term; } /** * Re-write query into primitive queries in the context of specified index * * @param Zend_Search_Lucene_Interface $index * @return Zend_Search_Lucene_Search_Query */ public function rewrite(Zend_Search_Lucene_Interface $index) { if (count($this->_terms) == 0) { return new Zend_Search_Lucene_Search_Query_Empty(); } // Check, that all fields are qualified $allQualified = true; foreach ($this->_terms as $term) { if ($term->field === null) { $allQualified = false; break; } } if ($allQualified) { return $this; } else { /** transform multiterm query to boolean and apply rewrite() method to subqueries. */ $query = new Zend_Search_Lucene_Search_Query_Boolean(); $query->setBoost($this->getBoost()); foreach ($this->_terms as $termId => $term) { $subquery = new Zend_Search_Lucene_Search_Query_Term($term); $query->addSubquery($subquery->rewrite($index), ($this->_signs === null)? true : $this->_signs[$termId]); } return $query; } } /** * Optimize query in the context of specified index * * @param Zend_Search_Lucene_Interface $index * @return Zend_Search_Lucene_Search_Query */ public function optimize(Zend_Search_Lucene_Interface $index) { $terms = $this->_terms; $signs = $this->_signs; foreach ($terms as $id => $term) { if (!$index->hasTerm($term)) { if ($signs === null || $signs[$id] === true) { // Term is required return new Zend_Search_Lucene_Search_Query_Empty(); } else { // Term is optional or prohibited // Remove it from terms and signs list unset($terms[$id]); unset($signs[$id]); } } } // Check if all presented terms are prohibited $allProhibited = true; if ($signs === null) { $allProhibited = false; } else { foreach ($signs as $sign) { if ($sign !== false) { $allProhibited = false; break; } } } if ($allProhibited) { return new Zend_Search_Lucene_Search_Query_Empty(); } /** * @todo make an optimization for repeated terms * (they may have different signs) */ if (count($terms) == 1) { // It's already checked, that it's not a prohibited term // It's one term query with one required or optional element $optimizedQuery = new Zend_Search_Lucene_Search_Query_Term(reset($terms)); $optimizedQuery->setBoost($this->getBoost()); return $optimizedQuery; } if (count($terms) == 0) { return new Zend_Search_Lucene_Search_Query_Empty(); } $optimizedQuery = new Zend_Search_Lucene_Search_Query_MultiTerm($terms, $signs); $optimizedQuery->setBoost($this->getBoost()); return $optimizedQuery; } /** * Returns query term * * @return array */ public function getTerms() { return $this->_terms; } /** * Return terms signs * * @return array */ public function getSigns() { return $this->_signs; } /** * Set weight for specified term * * @param integer $num * @param Zend_Search_Lucene_Search_Weight_Term $weight */ public function setWeight($num, $weight) { $this->_weights[$num] = $weight; } /** * Constructs an appropriate Weight implementation for this query. * * @param Zend_Search_Lucene_Interface $reader * @return Zend_Search_Lucene_Search_Weight */ public function createWeight(Zend_Search_Lucene_Interface $reader) { $this->_weight = new Zend_Search_Lucene_Search_Weight_MultiTerm($this, $reader); return $this->_weight; } /** * Calculate result vector for Conjunction query * (like '+something +another') * * @param Zend_Search_Lucene_Interface $reader */ private function _calculateConjunctionResult(Zend_Search_Lucene_Interface $reader) { $this->_resVector = null; if (count($this->_terms) == 0) { $this->_resVector = array(); } $resVectors = array();
$resVectorsSizes = array();
$resVectorsIds = array(); // is used to prevent arrays comparison
foreach ($this->_terms as $termId => $term) {
$resVectors[] = array_flip($reader->termDocs($term));
$resVectorsSizes[] = count(end($resVectors));
$resVectorsIds[] = $termId;
$this->_termsFreqs[$termId] = $reader->termFreqs($term);
}
// sort resvectors in order of subquery cardinality increasing
array_multisort($resVectorsSizes, SORT_ASC, SORT_NUMERIC,
$resVectorsIds, SORT_ASC, SORT_NUMERIC,
$resVectors);
foreach ($resVectors as $nextResVector) {
if($this->_resVector === null) { $this->_resVector = $nextResVector;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -