PHP项目搜索词分析与提示

wen PHP项目 1

本文目录导读:

PHP项目搜索词分析与提示

  1. 核心实现方案
  2. 前端实现
  3. 搜索词分析统计
  4. 性能优化建议
  5. 完整示例代码

我来为您详细分析PHP项目中的搜索词分析与提示功能实现方案。

搜索词分析与提示系统主要包含以下核心功能:

  1. 搜索词自动补全 - 用户输入时实时提供建议
  2. 搜索词联想 - 基于用户输入推荐相关搜索词
  3. 搜索趋势分析 - 统计和展示热门搜索词
  4. 搜索纠错 - 自动纠正拼写错误

核心实现方案

数据结构设计

// 搜索词表结构
CREATE TABLE search_terms (
    id INT PRIMARY KEY AUTO_INCREMENT,
    term VARCHAR(255) NOT NULL,
    frequency INT DEFAULT 1,
    last_searched DATETIME,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_term (term),
    INDEX idx_frequency (frequency DESC)
);
// 搜索日志表
CREATE TABLE search_logs (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,
    search_term VARCHAR(255),
    search_time DATETIME,
    ip_address VARCHAR(45),
    user_agent TEXT
);

搜索词提示类

<?php
class SearchSuggestion {
    private $db;
    public function __construct($db) {
        $this->db = $db;
    }
    /**
     * 获取搜索建议
     */
    public function getSuggestions($query, $limit = 10) {
        $query = trim($query);
        if (strlen($query) < 2) return [];
        $stmt = $this->db->prepare(
            "SELECT term, frequency 
             FROM search_terms 
             WHERE term LIKE ? 
             ORDER BY frequency DESC 
             LIMIT ?"
        );
        $searchPattern = $query . '%';
        $stmt->bind_param('si', $searchPattern, $limit);
        $stmt->execute();
        $result = $stmt->get_result();
        $suggestions = [];
        while ($row = $result->fetch_assoc()) {
            $suggestions[] = [
                'term' => $row['term'],
                'frequency' => $row['frequency'],
                'highlight' => $this->highlightMatch($row['term'], $query)
            ];
        }
        return $suggestions;
    }
    /**
     * 高亮匹配部分
     */
    private function highlightMatch($term, $query) {
        $pos = stripos($term, $query);
        if ($pos !== false) {
            return substr_replace($term, "<strong>$query</strong>", $pos, strlen($query));
        }
        return $term;
    }
}
?>

AJAX实时搜索接口

<?php
// search_suggest.php
header('Content-Type: application/json');
$query = $_GET['q'] ?? '';
$suggestion = new SearchSuggestion($db);
$suggestions = $suggestion->getSuggestions($query);
echo json_encode([
    'success' => true,
    'data' => $suggestions
]);
?>

前端实现

JavaScript自动补全

class SearchAutocomplete {
    constructor(inputElement, options = {}) {
        this.input = inputElement;
        this.options = {
            minChars: 2,
            delay: 300,
            maxResults: 10,
            ...options
        };
        this.suggestionBox = this.createSuggestionBox();
        this.init();
    }
    createSuggestionBox() {
        const box = document.createElement('div');
        box.className = 'search-suggestions';
        box.style.cssText = `
            position: absolute;
            background: white;
            border: 1px solid #ddd;
            max-height: 300px;
            overflow-y: auto;
            display: none;
            z-index: 1000;
        `;
        this.input.parentNode.appendChild(box);
        return box;
    }
    init() {
        let debounceTimer;
        this.input.addEventListener('input', (e) => {
            clearTimeout(debounceTimer);
            const value = e.target.value.trim();
            if (value.length < this.options.minChars) {
                this.hideSuggestions();
                return;
            }
            debounceTimer = setTimeout(() => {
                this.fetchSuggestions(value);
            }, this.options.delay);
        });
        // 关闭建议框
        document.addEventListener('click', (e) => {
            if (!this.input.contains(e.target) && !this.suggestionBox.contains(e.target)) {
                this.hideSuggestions();
            }
        });
    }
    async fetchSuggestions(query) {
        try {
            const response = await fetch(
                `search_suggest.php?q=${encodeURIComponent(query)}`
            );
            const data = await response.json();
            if (data.success) {
                this.renderSuggestions(data.data.slice(0, this.options.maxResults));
            }
        } catch (error) {
            console.error('获取搜索建议失败:', error);
        }
    }
    renderSuggestions(suggestions) {
        if (suggestions.length === 0) {
            this.hideSuggestions();
            return;
        }
        this.suggestionBox.innerHTML = suggestions.map(item => `
            <div class="suggestion-item" data-term="${item.term}">
                <span class="term">${item.highlight}</span>
                <small class="frequency">${item.frequency}次</small>
            </div>
        `).join('');
        this.suggestionBox.style.display = 'block';
        this.bindSuggestionEvents();
    }
    bindSuggestionEvents() {
        this.suggestionBox.querySelectorAll('.suggestion-item').forEach(item => {
            item.addEventListener('click', () => {
                this.input.value = item.dataset.term;
                this.hideSuggestions();
                this.input.dispatchEvent(new Event('submit'));
            });
        });
    }
    hideSuggestions() {
        this.suggestionBox.style.display = 'none';
    }
}
// 使用示例
const searchInput = document.getElementById('search-input');
new SearchAutocomplete(searchInput, {
    minChars: 2,
    delay: 300,
    maxResults: 10
});

搜索词分析统计

热门搜索统计

class SearchAnalysis {
    private $db;
    public function getHotSearches($days = 7, $limit = 20) {
        $stmt = $this->db->prepare(
            "SELECT search_term, COUNT(*) as count 
             FROM search_logs 
             WHERE search_time >= DATE_SUB(NOW(), INTERVAL ? DAY)
             GROUP BY search_term 
             ORDER BY count DESC 
             LIMIT ?"
        );
        $stmt->bind_param('ii', $days, $limit);
        $stmt->execute();
        return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    }
    public function getSearchTrend($term, $days = 30) {
        $stmt = $this->db->prepare(
            "SELECT DATE(search_time) as date, 
                    COUNT(*) as count 
             FROM search_logs 
             WHERE search_term = ? 
               AND search_time >= DATE_SUB(NOW(), INTERVAL ? DAY)
             GROUP BY DATE(search_time) 
             ORDER BY date"
        );
        $stmt->bind_param('si', $term, $days);
        $stmt->execute();
        return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    }
}

搜索词联想算法

class SearchAssociation {
    private $db;
    /**
     * 基于协同过滤的搜索联想
     */
    public function getRelatedTerms($term, $limit = 10) {
        // 找到搜索过该词的用户
        $stmt = $this->db->prepare(
            "SELECT DISTINCT user_id 
             FROM search_logs 
             WHERE search_term = ?"
        );
        $stmt->bind_param('s', $term);
        $stmt->execute();
        $users = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        if (empty($users)) return [];
        $userIds = array_column($users, 'user_id');
        $placeholders = implode(',', array_fill(0, count($userIds), '?'));
        // 查找这些用户搜索的其他词
        $stmt = $this->db->prepare(
            "SELECT search_term, COUNT(*) as count 
             FROM search_logs 
             WHERE user_id IN ($placeholders) 
               AND search_term != ? 
             GROUP BY search_term 
             ORDER BY count DESC 
             LIMIT ?"
        );
        $params = array_merge($userIds, [$term, $limit]);
        $types = str_repeat('i', count($userIds)) . 'si';
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
        return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    }
}

性能优化建议

缓存策略

class SearchCache {
    private $cache;
    private $ttl = 3600; // 1小时
    public function getSuggestions($query) {
        $cacheKey = "search_suggestions:" . md5($query);
        if ($cached = apcu_fetch($cacheKey)) {
            return $cached;
        }
        $suggestions = $this->fetchFromDB($query);
        apcu_store($cacheKey, $suggestions, $this->ttl);
        return $suggestions;
    }
}

数据库索引优化

-- 复合索引优化
ALTER TABLE search_terms ADD INDEX idx_term_freq (term(10), frequency DESC);
ALTER TABLE search_logs ADD INDEX idx_search_time_term (search_time, search_term);

完整示例代码

<?php
// SearchManager.php
class SearchManager {
    private $db;
    private $cache;
    public function __construct($db) {
        $this->db = $db;
        $this->cache = new SearchCache($db);
    }
    public function processSearch($term) {
        // 1. 记录搜索日志
        $this->logSearch($term);
        // 2. 更新搜索词频率
        $this->updateTermFrequency($term);
        // 3. 获取搜索建议
        $suggestions = $this->getSuggestions($term);
        // 4. 获取联想词
        $related = $this->getRelatedTerms($term);
        return [
            'suggestions' => $suggestions,
            'related' => $related,
            'hot_searches' => $this->getHotSearches()
        ];
    }
    private function logSearch($term) {
        $stmt = $this->db->prepare(
            "INSERT INTO search_logs (search_term, search_time) 
             VALUES (?, NOW())"
        );
        $stmt->bind_param('s', $term);
        $stmt->execute();
    }
    private function updateTermFrequency($term) {
        $stmt = $this->db->prepare(
            "INSERT INTO search_terms (term, frequency, last_searched) 
             VALUES (?, 1, NOW()) 
             ON DUPLICATE KEY UPDATE 
             frequency = frequency + 1, 
             last_searched = NOW()"
        );
        $stmt->bind_param('s', $term);
        $stmt->execute();
    }
}
?>

这个搜索词分析与提示系统核心优势:

  1. 实时响应 - 通过AJAX和缓存机制实现快速响应
  2. 智能联想 - 基于用户行为数据的关联推荐
  3. 性能优化 - 合理的索引设计和缓存策略
  4. 可扩展性 - 模块化设计便于功能扩展
  5. 数据分析 - 完整的搜索趋势分析能力

可以根据项目具体需求调整参数、优化算法或增加新功能。

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