概述

typecho 自带的搜索方式不好用,不支持分词操作

解决

为了缩小索引力度,可以修改 mysql 配置

[mysqld]
innodb_ft_min_token_size = 2
ft_min_word_len = 2
ngram_token_size = 2

更多详情可以查看:https://www.xiaoqiuyinboke.cn/archives/913.html

然后先添加全文索引

CREATE FULLTEXT INDEX ft_index_title ON blog_contents (title) WITH PARSER ngram;
CREATE FULLTEXT INDEX ft_index_text ON blog_contents (text) WITH PARSER ngram;

然后修改 php 代码

var/Widget/Archive.php:759 位置,也就是 $this->countSql = clone $select; 下一行,增加

$this->countSql->cleanAttribute("order");

如下图所示:

lpzl8vuy.png

最后修改 php 代码 searchHandle 方法

\Widget\Archive::searchHandle 方法里修改

private function searchHandle(Query $select, &$hasPushed)
    {
        /** 增加自定义搜索引擎接口 */
        //~ fix issue 40
        $keywords = $this->request->get('keywords');
        //$keywords = $this->request->filter('url', 'search')->keywords;
        self::pluginHandle()->trigger($hasPushed)->search($keywords, $this);

        if (!$hasPushed) {
            /** 搜索无法进入隐私项保护归档 */
            if ($this->user->hasLogin()) {
                //~ fix issue 941
                $select->where("table.contents.password IS NULL
                 OR table.contents.password = '' OR table.contents.authorId = ?", $this->user->uid);
            } else {
                $select->where("table.contents.password IS NULL OR table.contents.password = ''");
            }
            // 修改这里
            $select->select(
                "*",
                "MATCH(title)AGAINST('{$keywords}') AS score_title",
                "MATCH(text)AGAINST('{$keywords}') AS score_text"
            );
            // 注释原来的
            //$op = $this->db->getAdapter()->getDriver() == 'pgsql' ? 'ILIKE' : 'LIKE';
            //
            //$select->where("table.contents.title {$op} ? OR table.contents.text {$op} ?", $searchQuery, $searchQuery)
            //    ->where('table.contents.type = ?', 'post');
            // 增加这个
            $select->where('table.contents.password IS NULL')
                ->where("((MATCH(table.contents.title)AGAINST('{$keywords}')) OR (MATCH(table.contents.text)AGAINST('{$keywords}')))")
                ->where('table.contents.type = ?', 'post')
                ->order('score_title', Db::SORT_DESC)
                ->order('score_text', Db::SORT_DESC);
        }

        /** 设置关键词 */
        $this->keywords = $keywords;

        /** 设置分页 */
        $this->pageRow = ['keywords' => urlencode($keywords)];

        /** 设置头部feed */
        /** RSS 2.0 */
        $this->feedUrl = Router::url('search', ['keywords' => $keywords], $this->options->feedUrl);

        /** RSS 1.0 */
        $this->feedRssUrl = Router::url('search', ['keywords' => $keywords], $this->options->feedAtomUrl);

        /** ATOM 1.0 */
        $this->feedAtomUrl = Router::url('search', ['keywords' => $keywords], $this->options->feedAtomUrl);

        /** 设置标题 */
        $this->archiveTitle = $keywords;

        /** 设置归档类型 */
        $this->archiveType = 'search';

        /** 设置归档缩略名 */
        $this->archiveSlug = $keywords;

        /** 设置归档地址 */
        $this->archiveUrl = Router::url('search', ['keywords' => $keywords], $this->options->index);

        /** 插件接口 */
        self::pluginHandle()->searchHandle($this, $select);
    }
最后修改:2023 年 12 月 30 日
如果觉得我的文章对你有用,请随意赞赏