multiterm.php.svn-base
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· SVN-BASE 代码 · 共 585 行 · 第 1/2 页
SVN-BASE
585 行
* * @param Zend_Search_Lucene $reader * @return Zend_Search_Lucene_Search_Weight */ public function createWeight($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 $reader */ private function _calculateConjunctionResult($reader) { $this->_resVector = null; if (count($this->_terms) == 0) { $this->_resVector = array(); } foreach( $this->_terms as $termId=>$term ) { if($this->_resVector === null) { $this->_resVector = array_flip($reader->termDocs($term)); } else { $this->_resVector = array_intersect_key($this->_resVector, array_flip($reader->termDocs($term))); } if (count($this->_resVector) == 0) { // Empty result set, we don't need to check other terms break; } $this->_termsPositions[$termId] = $reader->termPositions($term); } ksort($this->_resVector, SORT_NUMERIC); } /** * Calculate result vector for non Conjunction query * (like '+something -another') * * @param Zend_Search_Lucene $reader */ private function _calculateNonConjunctionResult($reader) { $required = null; $optional = array(); $prohibited = array(); foreach ($this->_terms as $termId => $term) { $termDocs = array_flip($reader->termDocs($term)); if ($this->_signs[$termId] === true) { // required if ($required !== null) { // array intersection $required = array_intersect_key($required, $termDocs); } else { $required = $termDocs; } } elseif ($this->_signs[$termId] === false) { // prohibited // array union $prohibited += $termDocs; } else { // neither required, nor prohibited // array union $optional += $termDocs; } $this->_termsPositions[$termId] = $reader->termPositions($term); } if ($required !== null) { $this->_resVector = array_diff_key($required, $prohibited); } else { $this->_resVector = array_diff_key($optional, $prohibited); } ksort($this->_resVector, SORT_NUMERIC); } /** * Score calculator for conjunction queries (all terms are required) * * @param integer $docId * @param Zend_Search_Lucene $reader * @return float */ public function _conjunctionScore($docId, $reader) { if ($this->_coord === null) { $this->_coord = $reader->getSimilarity()->coord(count($this->_terms), count($this->_terms) ); } $score = 0.0; foreach ($this->_terms as $termId=>$term) { $score += $reader->getSimilarity()->tf(count($this->_termsPositions[$termId][$docId]) ) * $this->_weights[$termId]->getValue() * $reader->norm($docId, $term->field); } return $score * $this->_coord * $this->getBoost(); } /** * Score calculator for non conjunction queries (not all terms are required) * * @param integer $docId * @param Zend_Search_Lucene $reader * @return float */ public function _nonConjunctionScore($docId, $reader) { if ($this->_coord === null) { $this->_coord = array(); $maxCoord = 0; foreach ($this->_signs as $sign) { if ($sign !== false /* not prohibited */) { $maxCoord++; } } for ($count = 0; $count <= $maxCoord; $count++) { $this->_coord[$count] = $reader->getSimilarity()->coord($count, $maxCoord); } } $score = 0.0; $matchedTerms = 0; foreach ($this->_terms as $termId=>$term) { // Check if term is if ($this->_signs[$termId] !== false && // not prohibited isset($this->_termsPositions[$termId][$docId]) // matched ) { $matchedTerms++; $score += $reader->getSimilarity()->tf(count($this->_termsPositions[$termId][$docId]) ) * $this->_weights[$termId]->getValue() * $reader->norm($docId, $term->field); } } return $score * $this->_coord[$matchedTerms] * $this->getBoost(); } /** * Execute query in context of index reader * It also initializes necessary internal structures * * @param Zend_Search_Lucene $reader */ public function execute($reader) { if ($this->_signs === null) { $this->_calculateConjunctionResult($reader); } else { $this->_calculateNonConjunctionResult($reader); } // Initialize weight if it's not done yet $this->_initWeight($reader); } /** * Get document ids likely matching the query * * It's an array with document ids as keys (performance considerations) * * @return array */ public function matchedDocs() { return $this->_resVector; } /** * Score specified document * * @param integer $docId * @param Zend_Search_Lucene $reader * @return float */ public function score($docId, $reader) { if (isset($this->_resVector[$docId])) { if ($this->_signs === null) { return $this->_conjunctionScore($docId, $reader); } else { return $this->_nonConjunctionScore($docId, $reader); } } else { return 0; } } /** * Return query terms * * @return array */ public function getQueryTerms() { if ($this->_signs === null) { return $this->_terms; } $terms = array(); foreach ($this->_signs as $id => $sign) { if ($sign !== false) { $terms[] = $this->_terms[$id]; } } return $terms; } /** * Highlight query terms * * @param integer &$colorIndex * @param Zend_Search_Lucene_Document_Html $doc */ public function highlightMatchesDOM(Zend_Search_Lucene_Document_Html $doc, &$colorIndex) { $words = array(); if ($this->_signs === null) { foreach ($this->_terms as $term) { $words[] = $term->text; } } else { foreach ($this->_signs as $id => $sign) { if ($sign !== false) { $words[] = $this->_terms[$id]->text; } } } $doc->highlight($words, $this->_getHighlightColor($colorIndex)); } /** * Print a query * * @return string */ public function __toString() { // It's used only for query visualisation, so we don't care about characters escaping $query = ''; foreach ($this->_terms as $id => $term) { if ($id != 0) { $query .= ' '; } if ($this->_signs === null || $this->_signs[$id] === true) { $query .= '+'; } else if ($this->_signs[$id] === false) { $query .= '-'; } if ($term->field !== null) { $query .= $term->field . ':'; } $query .= $term->text; } if ($this->getBoost() != 1) { $query = '(' . $query . ')^' . $this->getBoost(); } return $query; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?