PHP项目如何实现同义词扩展?

wen java案例 2

本文目录导读:

PHP项目如何实现同义词扩展?

  1. 数据库存储方案(推荐中小型项目)
  2. 内存缓存方案(推荐高性能场景)
  3. 配置文件方案(简单小型项目)
  4. 搜索引擎集成方案(推荐全文搜索场景)
  5. 完整示例:搜索功能实现
  6. 性能优化建议
  7. 选择建议

在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
中文分词+同义词 集成中文分词插件

选择时需考虑:数据量大小、性能要求、更新频率、部署复杂度等因素。

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