boolean.php.svn-base

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· SVN-BASE 代码 · 共 710 行 · 第 1/2 页

SVN-BASE
710
字号
            $clause = new Zend_Search_Lucene_Search_Query_Term(reset($terms));            $clause->setBoost(reset($boostFactors));            $subqueries[] = $clause;            $signs[]      = reset($tsigns);            // Clear terms list            $terms = array();        } else if (count($terms) > 1  &&  count(array_unique($boostFactors)) == 1) {            $clause = new Zend_Search_Lucene_Search_Query_MultiTerm($terms, $tsigns);            $clause->setBoost(reset($boostFactors));            $subqueries[] = $clause;            // Clause sign is 'required' if clause contains required terms. 'Optional' otherwise.            $signs[]      = (in_array(true, $tsigns))? true : null;            // Clear terms list            $terms = array();        }        if (count($prohibitedTerms) == 1) {            // (boost factors are not significant for prohibited clauses)            $subqueries[] = new Zend_Search_Lucene_Search_Query_Term(reset($prohibitedTerms));            $signs[]      = false;            // Clear prohibited terms list            $prohibitedTerms = array();        } else if (count($prohibitedTerms) > 1) {            // prepare signs array            $prohibitedSigns = array();            foreach ($prohibitedTerms as $id => $term) {                // all prohibited term are grouped as optional into multi-term query                $prohibitedSigns[$id] = null;            }            // (boost factors are not significant for prohibited clauses)            $subqueries[] = new Zend_Search_Lucene_Search_Query_MultiTerm($prohibitedTerms, $prohibitedSigns);            // Clause sign is 'prohibited'            $signs[]      = false;            // Clear terms list            $prohibitedTerms = array();        }        /** @todo Group terms with the same boost factors together */        // Check, that all terms are processed        // Replace candidate for optimized query        if (count($terms) == 0  &&  count($prohibitedTerms) == 0) {            $optimizedQuery = new Zend_Search_Lucene_Search_Query_Boolean($subqueries, $signs);            $optimizedQuery->setBoost($this->getBoost());        }        return $optimizedQuery;    }    /**     * Returns subqueries     *     * @return array     */    public function getSubqueries()    {        return $this->_subqueries;    }    /**     * Return subqueries signs     *     * @return array     */    public function getSigns()    {        return $this->_signs;    }    /**     * Constructs an appropriate Weight implementation for this query.     *     * @param Zend_Search_Lucene $reader     * @return Zend_Search_Lucene_Search_Weight     */    public function createWeight($reader)    {        $this->_weight = new Zend_Search_Lucene_Search_Weight_Boolean($this, $reader);        return $this->_weight;    }    /**     * Calculate result vector for Conjunction query     * (like '<subquery1> AND <subquery2> AND <subquery3>')     */    private function _calculateConjunctionResult()    {        $this->_resVector = null;        if (count($this->_subqueries) == 0) {            $this->_resVector = array();        }        foreach ($this->_subqueries as $subquery) {            if($this->_resVector === null) {                $this->_resVector = $subquery->matchedDocs();            } else {                $this->_resVector = array_intersect_key($this->_resVector, $subquery->matchedDocs());            }            if (count($this->_resVector) == 0) {                // Empty result set, we don't need to check other terms                break;            }        }        ksort($this->_resVector, SORT_NUMERIC);    }    /**     * Calculate result vector for non Conjunction query     * (like '<subquery1> AND <subquery2> AND NOT <subquery3> OR <subquery4>')     */    private function _calculateNonConjunctionResult()    {        $required   = null;        $optional   = array();        foreach ($this->_subqueries as $subqueryId => $subquery) {            $docs = $subquery->matchedDocs();            if ($this->_signs[$subqueryId] === true) {                // required                if ($required !== null) {                    // array intersection                    $required = array_intersect_key($required, $docs);                } else {                    $required = $docs;                }            } elseif ($this->_signs[$subqueryId] === false) {                // prohibited                // Do nothing. matchedDocs() may include non-matching id's            } else {                // neither required, nor prohibited                // array union                $optional += $docs;            }        }        if ($required !== null) {            $this->_resVector = &$required;        } else {            $this->_resVector = &$optional;        }        ksort($this->_resVector, SORT_NUMERIC);    }    /**     * Score calculator for conjunction queries (all subqueries 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->_subqueries),                                                            count($this->_subqueries) );        }        $score = 0;        foreach ($this->_subqueries as $subquery) {            $score += $subquery->score($docId, $reader) * $this->_coord;        }        return $score * $this->_coord * $this->getBoost();    }    /**     * Score calculator for non conjunction queries (not all subqueries 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;        $matchedSubqueries = 0;        foreach ($this->_subqueries as $subqueryId => $subquery) {            $subscore = $subquery->score($docId, $reader);            // Prohibited            if ($this->_signs[$subqueryId] === false && $subscore != 0) {                return 0;            }            // is required, but doen't match            if ($this->_signs[$subqueryId] === true &&  $subscore == 0) {                return 0;            }            if ($subscore != 0) {                $matchedSubqueries++;                $score += $subscore;            }        }        return $score * $this->_coord[$matchedSubqueries] * $this->getBoost();    }    /**     * Execute query in context of index reader     * It also initializes necessary internal structures     *     * @param Zend_Search_Lucene $reader     */    public function execute($reader)    {        // Initialize weight if it's not done yet        $this->_initWeight($reader);        foreach ($this->_subqueries as $subquery) {            $subquery->execute($reader);        }        if ($this->_signs === null) {            $this->_calculateConjunctionResult();        } else {            $this->_calculateNonConjunctionResult();        }    }    /**     * 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()    {        $terms = array();        foreach ($this->_subqueries as $id => $subquery) {            if ($this->_signs === null  ||  $this->_signs[$id] !== false) {                $terms = array_merge($terms, $subquery->getQueryTerms());            }        }        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)    {        foreach ($this->_subqueries as $id => $subquery) {            if ($this->_signs === null  ||  $this->_signs[$id] !== false) {                $subquery->highlightMatchesDOM($doc, $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->_subqueries as $id => $subquery) {            if ($id != 0) {                $query .= ' ';            }            if ($this->_signs === null || $this->_signs[$id] === true) {                $query .= '+';            } else if ($this->_signs[$id] === false) {                $query .= '-';            }            $query .= '(' . $subquery->__toString() . ')';            if ($subquery->getBoost() != 1) {                $query .= '^' . $subquery->getBoost();            }        }        return $query;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?