分享经验 版主:论坛审计组
最简单实现 实现分词搜索功能 实现真正模糊搜索
类型:迅睿CMS 更新时间:2025-10-24 16:39:56 搜索功能

搜索实现分词搜索功能


实现原理:

如 “装修二级” 拆分为 “装”“修”“二”“级”,只要目标内容包含这几个字即可匹配,无需考虑顺序和同义词。



找到搜索文件  /dayrui/App/Module/Models/Search.php  

大约187行 注释掉下面这个代码

        // 关键字匹配条件
        if ($param['keyword'] != '') {
            $temp = [];
            $sfield = explode(',', $this->module['setting']['search']['field'] ? $this->module['setting']['search']['field'] : 'title,keywords');
            $search_keyword = explode('|', addslashes((string)$param['keyword']));
            foreach ($search_keyword as $kw) {
                $is = 0;
                if ($sfield) {
                    foreach ($sfield as $t) {
                        if ($t && dr_in_array($t, $field)) {
                            $is = 1;
                            $temp[] = $this->module['setting']['search']['complete'] ? '`'.$table.'`.`'.$t.'` = \''.$kw.'\'' : '`'.$table.'`.`'.$t.'` LIKE \'%'.$kw.'%\'';
                        }
                    }
                }
                if (!$is) {
                    $temp[] = $this->module['setting']['search']['complete'] ? '`'.$table.'`.`title` = \''.$kw.'\'' : '`'.$table.'`.`title` LIKE \'%'.$kw.'%\'';
                }
            }
            $where['keyword'] = $temp ? '('.implode(' OR ', $temp).')' : '';
            $param_new['keyword'] = $search_keyword;
        }



然后下面增加 

    // 关键字匹配条件(分词搜索:拆分单个字符,匹配所有字符)
    if ($param['keyword'] != '') {
        $temp = [];
        $sfield = explode(',', $this->module['setting']['search']['field'] ? $this->module['setting']['search']['field'] : 'title,keywords');
        $original_kw = addslashes((string)$param['keyword']);
        
        // 拆分关键词为单个字符(支持汉字)
        $chars = [];
        $length = mb_strlen($original_kw, 'UTF-8');
        for ($i = 0; $i < $length; $i++) {
            $char = mb_substr($original_kw, $i, 1, 'UTF-8');
            // 过滤空字符和特殊符号
            if ($char && preg_match('/[\p{Han}\d]/u', $char)) {
                $chars[] = $char;
            }
        }
        
        // 如果有有效字符则构建条件
        if (!empty($chars)) {
            foreach ($chars as $char) {
                $char_conditions = [];
                // 对每个搜索字段添加包含当前字符的条件
                if ($sfield) {
                    foreach ($sfield as $t) {
                        if ($t && dr_in_array($t, $field)) {
                            $char_conditions[] = '`'.$table.'`.`'.$t.'` LIKE \'%'.$char.'%\'';
                        }
                    }
                }
                // 如果没有指定字段,默认用title
                if (empty($char_conditions)) {
                    $char_conditions[] = '`'.$table.'`.`title` LIKE \'%'.$char.'%\'';
                }
                // 每个字符必须至少匹配一个字段(用OR连接字段,用AND连接不同字符)
                $temp[] = '('.implode(' OR ', $char_conditions).')';
            }
            // 所有字符条件用AND连接(必须包含所有字符)
            $where['keyword'] = $temp ? '('.implode(' AND ', $temp).')' : '';
        }
        $param_new['keyword'] = $original_kw;
    }



既可以实现分词搜索。