PHP 搜索权重怎么设置

wen PHP项目 2

本文目录导读:

PHP 搜索权重怎么设置

  1. 使用 MySQL(高级:全文索引 + 权重)
  2. 使用 Elasticsearch(专业搜索)
  3. 纯 PHP 数组排序(轻量级)
  4. 数据库通用方案(MySQL + PHP 计算)
  5. 总结建议

在 PHP 中设置搜索权重通常不是指 PHP 语言本身的配置,而是指在业务逻辑中实现搜索结果的排序算法,这主要取决于你使用的是关系型数据库(MySQL)、全文搜索引擎(Elasticsearch)还是纯 PHP 数组

以下是三种最常见的实现方式,按推荐程度排序:


使用 MySQL(高级:全文索引 + 权重)

如果你用的是 MySQL 5.7+ 或 8.0,推荐使用内置的 FULLTEXT 索引,它支持自然语言模式,且可以通过 BOOLEAN MODE 配合 、、>(提高权重)等操作符。

场景: 搜索商品名称和描述,希望标题匹配的排前面。

<?php
$keyword = 'PHP 教程';
// 使用布尔模式,给“标题”字段增加权重
$sql = "SELECT 
            id, 
            title, 
            description,
            // 计算相关度分数(自定义权重计算)
            (CASE 
                WHEN title LIKE '%".$keyword."%' THEN 10 
                ELSE 0 
            END) + 
            (CASE 
                WHEN description LIKE '%".$keyword."%' THEN 5 
                ELSE 0 
            END) AS relevance_score 
        FROM articles 
        WHERE title LIKE '%".$keyword."%' OR description LIKE '%".$keyword."%'
        ORDER BY relevance_score DESC, views DESC";
// 更高效的方案:使用 MySQL 原生的 MATCH AGAINST
$sql_native = "SELECT 
                id, 
                title,
                // 给标题字段乘以2的权重(需要字段在FULLTEXT里)
                (MATCH(title) AGAINST('".$keyword."') * 2 + MATCH(description) AGAINST('".$keyword."')) AS relevance 
              FROM articles 
              WHERE MATCH(title, description) AGAINST('".$keyword."' IN BOOLEAN MODE)
              ORDER BY relevance DESC";
?>

注意: MATCH...AGAINST 性能最优,但需要在建表时加上 FULLTEXT(title, description) 索引。


使用 Elasticsearch(专业搜索)

如果你需要复杂的打分、同义词、拼音、分词,ES 是工业级标准,权重通过 boost 参数设置。

<?php
// 假设使用官方客户端
$params = [
    'index' => 'articles',
    'body' => [
        'query' => [
            'bool' => [
                'should' => [
                    // 标题匹配,权重为 3(更关键)
                    [
                        'match' => [
                            'title' => [
                                'query' => 'PHP 教程',
                                'boost' => 3
                            ]
                        ]
                    ],
                    // 标签匹配,权重为 2
                    [
                        'match' => [
                            'tags' => [
                                'query' => 'PHP',
                                'boost' => 2
                            ]
                        ]
                    ],
                    // 内容匹配,权重为 1(最低)
                    [
                        'match' => [
                            'content' => [
                                'query' => '教程',
                                'boost' => 1
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];
?>

纯 PHP 数组排序(轻量级)

如果数据量很小,且没有数据库,可以在内存中用 usort 实现加权排序。

场景: 从 API 获取数据后,在本地根据关键词加权排序。

<?php
$data = [
    ['title' => 'PHP入门教程', 'content' => '基础', 'tags' => ['PHP']],
    ['title' => 'Java高级', 'content' => 'PHP实战', 'tags' => ['Java']],
    ['title' => '实战PHP', 'content' => '进阶', 'tags' => ['PHP', 'MySQL']],
];
$keyword = 'PHP';
// 计算每个元素的权重
$scored = array_map(function ($item) use ($keyword) {
    $score = 0;
    // 权重分配:标题命中 +5,标签命中 +3,内容命中 +1
    if (stripos($item['title'], $keyword) !== false) {
        $score += 5;
    }
    if (in_array($keyword, $item['tags'])) {
        $score += 3;
    }
    if (stripos($item['content'], $keyword) !== false) {
        $score += 1;
    }
    // 加入原始数据
    $item['_score'] = $score;
    return $item;
}, $data);
// 按权重降序排序
usort($scored, function ($a, $b) {
    return $b['_score'] - $a['_score'];
});
// 过滤掉0权重的结果
$results = array_filter($scored, function ($item) {
    return $item['_score'] > 0;
});
print_r($results);
?>

数据库通用方案(MySQL + PHP 计算)

如果你没有全文索引,但需要灵活的权重控制,可以纯 SQL 计算,但注意性能。

SELECT *,
       (CASE 
           WHEN title LIKE '%关键词%' THEN 10 
           WHEN tags LIKE '%关键词%' THEN 5 
           WHEN content LIKE '%关键词%' THEN 2 
           ELSE 0 
       END) AS weight
FROM posts
WHERE title LIKE '%关键词%' OR tags LIKE '%关键词%' OR content LIKE '%关键词%'
ORDER BY weight DESC, created_at DESC;

总结建议

  1. 数据 < 1万条:用 PHP 数组方案或 MySQL LIKE + CASE WHEN,简单直接。
  2. 数据 1万~100万:用 MySQL FULLTEXT BOOLEAN MODE,性能好。
  3. 数据 > 100万 或需中文分词/复杂排序:必须上 Elasticsearch(或 Sphinx),权重设置才有效果。

如果你告诉我具体的数据结构(表字段)和数据量,可以给你写一个更精确的 SQL 示例。

抱歉,评论功能暂时关闭!