怎么修改代码把WordPress的搜索改成模糊搜索

要将WordPress的默认搜索改为支持模糊搜索(部分关键词匹配),可以通过以下步骤修改主题的 functions.php 文件:

// 在functions.php中添加以下代码
function fuzzy_search_query($search, $wp_query) {
    global $wpdb;

    if (empty($wp_query->query_vars['s']) || !$wp_query->is_main_query()) {
        return $search;
    }

    // 获取用户输入的搜索词
    $terms = $wp_query->query_vars['s'];
    
    // 拆分多个关键词为数组
    $terms = explode(' ', $terms);

    // 构建模糊搜索条件
    $search = '';
    foreach ($terms as $term) {
        $term = esc_sql($wpdb->esc_like($term));
        $search .= " AND ({$wpdb->posts}.post_title LIKE '%{$term}%'";
        $search .= " OR {$wpdb->posts}.post_content LIKE '%{$term}%')";
    }

    // 可选:同时保留默认的精确搜索条件(用OR连接)
    // $search = preg_replace('/^ AND /', ' OR ', $search);

    return $search;
}
add_filter('posts_search', 'fuzzy_search_query', 10, 2);

代码说明:

  1. 获取搜索词:从查询参数中提取用户输入的关键词
  2. 拆分关键词:支持处理多个空格分隔的搜索词(如:”hello world”)
  3. 构建LIKE条件
    • 每个关键词前后添加%通配符,实现任意位置匹配
    • 同时在标题(post_title)和内容(post_content)中搜索
  4. 保留默认条件(可选):
    • 注释部分展示了如何保留原生精确搜索(使用OR连接)

扩展优化:

// 高级版:提升性能并扩展搜索范围
function advanced_fuzzy_search($search, $wp_query) {
    global $wpdb;

    if (!$wp_query->is_search() || !$wp_query->is_main_query()) {
        return $search;
    }

    $terms = get_query_var('s');
    $exact_match = false; // 是否保留精确匹配

    // 处理带引号的精确搜索(原生行为)
    if (preg_match('/^".+"$/', $terms)) {
        $exact_match = true;
        $terms = trim($terms, '"');
    }

    $terms = explode(' ', $terms);

    $search_conditions = [];
    foreach ($terms as $term) {
        $term = esc_sql($wpdb->esc_like($term));
        
        // 构建多字段模糊条件
        $conditions = [
            "{$wpdb->posts}.post_title LIKE '%{$term}%'",
            "{$wpdb->posts}.post_content LIKE '%{$term}%'",
            "{$wpdb->posts}.post_excerpt LIKE '%{$term}%'",
            "{$wpdb->postmeta}.meta_value LIKE '%{$term}%'"
        ];
        
        $search_conditions[] = '('.implode(' OR ', $conditions).')';
    }

    // 组合条件(AND/OR逻辑)
    $operator = ' AND '; // 默认多个关键词使用AND逻辑
    // $operator = ' OR '; // 改为OR逻辑则匹配任一关键词
    
    $search = ' AND ('.implode($operator, $search_conditions).')';

    // 包含自定义字段搜索(需要JOIN postmeta表)
    if (!$wp_query->get('join_postmeta')) {
        add_filter('posts_join', function($join) use ($wpdb) {
            $join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id ";
            return $join;
        });
        $wp_query->set('join_postmeta', true);
    }

    // 去重结果
    add_filter('posts_distinct', function() {
        return 'DISTINCT';
    });

    return $exact_match ? $original_search : $search;
}
add_filter('posts_search', 'advanced_fuzzy_search', 20, 2);

使用建议:

  1. 性能优化
    • 对于大型站点,建议:
      • 添加搜索缓存机制
      • 使用MySQL的全文索引(FULLTEXT)
      • 考虑使用专用搜索引擎(如ElasticSearch)
  2. 排序优化
    // 按匹配度排序(标题匹配优先)
    add_filter('posts_orderby', function($orderby, $query) {
        if ($query->is_search()) {
            global $wpdb;
            return "(
                CASE
                    WHEN {$wpdb->posts}.post_title LIKE '%{$term}%' THEN 1
                    WHEN {$wpdb->posts}.post_content LIKE '%{$term}%' THEN 2
                    ELSE 3
                END
            ) ASC, {$wpdb->posts}.post_date DESC";
        }
        return $orderby;
    }, 10, 2);
  3. 注意事项
    • 通配符在前(%term)会导致全表扫描,大数据量时影响性能
    • 需要处理SQL注入风险(已通过esc_sqlesc_like防范)
    • 可能与其他搜索插件冲突

测试方法:

  1. 输入部分关键词(如用”press”匹配”WordPress”)
  2. 测试多关键词组合(如”word press”应匹配”wordpress”)
  3. 检查特殊字符处理(如带符号的搜索词)

本文来自投稿,不代表瓜5博客立场,如若转载,请注明出处:https://blog.gua5.com/xing/146

喜欢 (1)

发表回复

登录后才能评论

猜你喜欢