本文目录导读:

在 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万条:用 PHP 数组方案或 MySQL
LIKE+CASE WHEN,简单直接。 - 数据 1万~100万:用 MySQL
FULLTEXTBOOLEAN MODE,性能好。 - 数据 > 100万 或需中文分词/复杂排序:必须上 Elasticsearch(或 Sphinx),权重设置才有效果。
如果你告诉我具体的数据结构(表字段)和数据量,可以给你写一个更精确的 SQL 示例。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播