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 + -
显示快捷键?