本文目录导读:

在PHP项目中实现同义词扩展,通常有以下几种常见方法,具体选择取决于你的项目需求和数据规模:
数据库存储方案(推荐中小型项目)
创建同义词表
CREATE TABLE synonyms (
id INT PRIMARY KEY AUTO_INCREMENT,
word VARCHAR(255) NOT NULL,
synonym VARCHAR(255) NOT NULL,
group_id INT NOT NULL,
UNIQUE KEY unique_pair (word, synonym)
);
-- 创建索引
CREATE INDEX idx_word ON synonyms(word);
CREATE INDEX idx_group ON synonyms(group_id);
插入示例数据
INSERT INTO synonyms (word, synonym, group_id) VALUES
('快乐', '高兴', 1),
('快乐', '愉快', 1),
('高兴', '快乐', 1),
('高兴', '愉快', 1),
('快速', '迅速', 2),
('快速', '敏捷', 2);
PHP查询示例
class SynonymManager {
private $db;
public function __construct(PDO $db) {
$this->db = $db;
}
// 获取所有同义词
public function getSynonyms(string $word): array {
$stmt = $this->db->prepare("
SELECT synonym FROM synonyms
WHERE word = ?
");
$stmt->execute([$word]);
return $stmt->fetchAll(PDO::FETCH_COLUMN);
}
// 扩展搜索关键词
public function expandQuery(string $query): array {
$words = explode(' ', $query);
$expandedWords = [$words];
foreach ($words as $word) {
$synonyms = $this->getSynonyms($word);
if (!empty($synonyms)) {
$expandedWords[] = $synonyms;
}
}
return array_unique(array_merge(...$expandedWords));
}
}
内存缓存方案(推荐高性能场景)
使用Redis存储
class RedisSynonymManager {
private $redis;
public function __construct(Redis $redis) {
$this->redis = $redis;
}
// 加载同义词到Redis
public function loadSynonyms(array $synonymGroups): void {
foreach ($synonymGroups as $groupId => $words) {
$key = "synonyms:group:{$groupId}";
$this->redis->sAddArray($key, $words);
// 建立反向索引
foreach ($words as $word) {
$this->redis->sAdd("synonyms:word:{$word}", ...$words);
$this->redis->sRem("synonyms:word:{$word}", $word); // 移除自身
}
}
}
// 获取同义词
public function getSynonyms(string $word): array {
return $this->redis->sMembers("synonyms:word:{$word}") ?? [];
}
}
配置文件方案(简单小型项目)
synonyms.json
{
"group1": ["快乐", "高兴", "愉快", "欢乐"],
"group2": ["快速", "迅速", "敏捷", "迅猛"],
"group3": ["美丽", "漂亮", "好看", "迷人"]
}
PHP实现
class ConfigSynonymManager {
private array $synonyms;
private array $reverseIndex = [];
public function __construct(string $configFile) {
$this->synonyms = json_decode(file_get_contents($configFile), true);
$this->buildReverseIndex();
}
private function buildReverseIndex(): void {
foreach ($this->synonyms as $group => $words) {
foreach ($words as $word) {
$this->reverseIndex[$word] = array_diff($words, [$word]);
}
}
}
public function getSynonyms(string $word): array {
return $this->reverseIndex[$word] ?? [];
}
}
搜索引擎集成方案(推荐全文搜索场景)
使用Elasticsearch
class ElasticsearchSynonymManager {
private $client;
public function __construct() {
$this->client = Elasticsearch\ClientBuilder::create()->build();
}
// 创建带同义词的分析器
public function setupSynonymAnalyzer(): void {
$params = [
'index' => 'my_index',
'body' => [
'settings' => [
'analysis' => [
'filter' => [
'my_synonym_filter' => [
'type' => 'synonym',
'synonyms' => [
'快乐, 高兴, 愉快',
'快速, 迅速, 敏捷'
]
]
],
'analyzer' => [
'my_synonym_analyzer' => [
'tokenizer' => 'standard',
'filter' => ['lowercase', 'my_synonym_filter']
]
]
]
]
]
];
$this->client->indices()->create($params);
}
}
完整示例:搜索功能实现
<?php
class SearchEngine {
private SynonymManager $synonymManager;
private DatabaseManager $db;
public function search(string $query): array {
// 1. 扩展关键词
$expandedTerms = $this->expandTerms($query);
// 2. 构建搜索SQL
$sql = $this->buildSearchQuery($expandedTerms);
// 3. 执行搜索
return $this->db->query($sql)->fetchAll();
}
private function expandTerms(string $query): array {
$terms = explode(' ', $query);
$allTerms = [];
foreach ($terms as $term) {
$allTerms[] = $term;
$synonyms = $this->synonymManager->getSynonyms($term);
$allTerms = array_merge($allTerms, $synonyms);
}
return array_unique($allTerms);
}
private function buildSearchQuery(array $terms): string {
$likeClauses = [];
foreach ($terms as $term) {
$likeClauses[] = "content LIKE '%" . $this->db->escape($term) . "%'";
}
return "SELECT * FROM articles WHERE " . implode(' OR ', $likeClauses);
}
}
性能优化建议
索引优化
// 使用Trie树优化大词汇表
class TrieSynonymManager {
private TrieNode $root;
public function buildSynonymTrie(array $synonymData): void {
foreach ($synonymData as $word => $synonyms) {
$current = $this->root;
foreach (str_split($word) as $char) {
if (!isset($current->children[$char])) {
$current->children[$char] = new TrieNode();
}
$current = $current->children[$char];
}
$current->synonyms = $synonyms;
}
}
public function getSynonyms(string $word): array {
$current = $this->root;
foreach (str_split($word) as $char) {
if (!isset($current->children[$char])) {
return [];
}
$current = $current->children[$char];
}
return $current->synonyms ?? [];
}
}
缓存策略
class CachedSynonymManager {
private $cache;
private $ttl = 3600; // 1小时缓存
public function getSynonyms(string $word): array {
$cacheKey = "synonym:{$word}";
// 尝试从缓存获取
if ($cached = $this->cache->get($cacheKey)) {
return $cached;
}
// 从数据库获取
$synonyms = $this->fetchFromDatabase($word);
// 存入缓存
$this->cache->set($cacheKey, $synonyms, $this->ttl);
return $synonyms;
}
}
选择建议
| 场景 | 推荐方案 |
|---|---|
| 小型项目、词汇量小 | 配置文件方案 |
| 中大型项目、需要持久化 | 数据库方案 |
| 高性能、大并发 | Redis缓存 |
| 全文搜索 | Elasticsearch |
| 中文分词+同义词 | 集成中文分词插件 |
选择时需考虑:数据量大小、性能要求、更新频率、部署复杂度等因素。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播