php实现全文检索
PHP实现全文检索的方法
使用MySQL的全文检索功能
MySQL提供了全文检索功能,适用于InnoDB和MyISAM引擎。需要在表中创建FULLTEXT索引,然后使用MATCH AGAINST语法进行查询。
-- 创建表时添加全文索引
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content TEXT,
FULLTEXT(title, content)
);
-- 使用全文检索查询
SELECT * FROM articles WHERE MATCH(title, content) AGAINST('搜索关键词');
PHP代码示例:
$keyword = 'PHP教程';
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$stmt = $pdo->prepare("SELECT * FROM articles WHERE MATCH(title, content) AGAINST(:keyword)");
$stmt->bindValue(':keyword', $keyword);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
使用Elasticsearch
Elasticsearch是专业的全文搜索引擎,性能强大但需要额外安装和配置。
安装Elasticsearch客户端:
composer require elasticsearch/elasticsearch
PHP代码示例:
require 'vendor/autoload.php';
$client = Elastic\Elasticsearch\ClientBuilder::create()->build();
$params = [
'index' => 'articles',
'body' => [
'query' => [
'match' => [
'content' => 'PHP教程'
]
]
]
];
$response = $client->search($params);
$results = $response['hits']['hits'];
使用Sphinx搜索引擎
Sphinx是开源的全文搜索引擎,支持高速索引和搜索。
配置示例(sphinx.conf):
source articles {
type = mysql
sql_host = localhost
sql_user = username
sql_pass = password
sql_db = test
sql_query = SELECT id, title, content FROM articles
}
index articles {
source = articles
path = /var/data/articles
docinfo = extern
mlock = 0
morphology = stem_en
}
searchd {
listen = 9312
log = /var/log/sphinx/searchd.log
query_log = /var/log/sphinx/query.log
}
PHP代码示例:
$sphinx = new SphinxClient();
$sphinx->SetServer('localhost', 9312);
$result = $sphinx->Query('PHP教程', 'articles');
$matches = $result['matches'];
使用SQLite的FTS扩展
SQLite提供FTS(全文搜索)扩展模块,适合轻量级应用。
$db = new SQLite3(':memory:');
$db->exec('CREATE VIRTUAL TABLE docs USING fts5(title, content)');
$db->exec("INSERT INTO docs VALUES('PHP教程', '学习PHP编程语言')");
$results = $db->query("SELECT * FROM docs WHERE docs MATCH 'PHP'");
while ($row = $results->fetchArray()) {
print_r($row);
}
使用纯PHP实现简单全文检索
对于小型应用,可以用PHP数组和字符串函数实现简单检索:
function simpleSearch($docs, $query) {
$results = [];
$queryTerms = explode(' ', strtolower($query));
foreach ($docs as $id => $doc) {
$text = strtolower($doc['title'] . ' ' . $doc['content']);
$matchCount = 0;
foreach ($queryTerms as $term) {
if (strpos($text, $term) !== false) {
$matchCount++;
}
}
if ($matchCount > 0) {
$results[$id] = [
'doc' => $doc,
'score' => $matchCount / count($queryTerms)
];
}
}
uasort($results, function($a, $b) {
return $b['score'] <=> $a['score'];
});
return array_column($results, 'doc');
}
选择方案时应考虑数据量、性能需求和技术复杂度。MySQL全文检索适合中小型应用,Elasticsearch适合大型复杂搜索需求,Sphinx提供平衡的性能和功能,SQLite适合嵌入式应用,纯PHP实现仅适用于极小规模数据。







