1

据我了解,在阅读文档(尤其是评分部分)后,我添加的每个字段在对搜索结果进行评分时都具有相同的重要性。我有以下代码:

protected static $_indexPath = 'tmp/search/indexes/projects';

public static function createSearchIndex()
{
    $_index = new Zend_Search_Lucene(APPLICATION_PATH . self::$_indexPath, true);

    $_projects_stmt = self::getProjectsStatement();
    $_count = 0;

    while ($row = $_projects_stmt->fetch()) {

        $doc = new Zend_Search_Lucene_Document();

        $doc->addField(Zend_Search_Lucene_Field::text('name', $row['name']));
        $doc->addField(Zend_Search_Lucene_Field::text('description', $row['description']));
        $doc->addField(Zend_Search_Lucene_Field::unIndexed('projectId', $row['id']));

        $_index->addDocument($doc);
    }

    $_index->optimize();
    $_index->commit();
}

代码很简单 - 我正在生成索引,基于从 db 获取的数据,并将其保存在指定的位置。

我在很多地方寻找,因为我想要的行为是该name字段比description(比如说 75% 和 25%)更重要。因此,当我搜索某个短语时,它会在第一个文档的描述和第二个文档的名称中找到,那么第二个文档的分数实际上会高 3 倍,并且会在我的列表中显示得更高。

有没有办法以这种方式控制评分/排序?

4

1 回答 1

1

我是根据这个文档页面找到的。您需要创建新的Similarity算法类,并覆盖lengthNorm方法。Default我从类中复制了这个方法,添加了$multiplier变量,并在需要时设置它的值(对于我想要的列):

class Zend_Search_Lucene_Search_Similarity_Projects extends Zend_Search_Lucene_Search_Similarity_Default
{
    /**
     * @param string $fieldName
     * @param integer $numTerms
     * @return float
     */
    public function lengthNorm($fieldName, $numTerms)
    {
        if ($numTerms == 0) {
            return 1E10;
        }

        $multiplier = 1;

        if($fieldName == 'name') {
            $multiplier = 3;
        }

        return 1.0/sqrt($numTerms / $multiplier);
    }
}

然后,您唯一需要做的事情(从问题中编辑代码)就是Similarity在索引之前将您的新算法类设置为默认方法:

protected static $_indexPath = 'tmp/search/indexes/projects';

public static function createSearchIndex()
{
    Zend_Search_Lucene_Search_Similarity::setDefault(new Zend_Search_Lucene_Search_Similarity_Projects());

    $_index = new Zend_Search_Lucene(APPLICATION_PATH . self::$_indexPath, true);

    $_projects_stmt = self::getProjectsStatement();
    $_count = 0;

    while ($row = $_projects_stmt->fetch()) {

        $doc = new Zend_Search_Lucene_Document();

        $doc->addField(Zend_Search_Lucene_Field::text('name', $row['name']));
        $doc->addField(Zend_Search_Lucene_Field::text('description', $row['description']));
        $doc->addField(Zend_Search_Lucene_Field::unIndexed('projectId', $row['id']));

        $_index->addDocument($doc);
    }

    $_index->optimize();
    $_index->commit();
}

我想额外提升name领域,但你可以和任何人一起做。

于 2013-04-02T03:34:55.380 回答