You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP数字图书馆推荐引擎:MySQL关键词无法单字匹配的问题求助

解决PHP数字图书馆推荐引擎的关键词匹配问题

这个问题我做类似推荐功能时也踩过坑!完全匹配整串关键词确实太死板了,咱们改成按单个关键词匹配,只要用户阅读的图书和其他图书有至少一个共同关键词就生成推荐,下面给你两种可行的实现方案:

方案1:直接基于现有关键词字符串字段改造

如果你的图书关键词是存在数据库的keywords字段(比如空格分隔的字符串,像"money investment"),可以通过拆分关键词+构建模糊查询来实现:

步骤1:拆分当前图书的关键词

先把当前图书的关键词拆成单个词的数组,同时去重、过滤空值:

// 假设你用PDO操作数据库,当前图书ID为$currentBookId
$currentBookId = 1;
$currentBook = $pdo->query("SELECT keywords FROM books WHERE id = {$currentBookId}")->fetch(PDO::FETCH_ASSOC);

// 拆分关键词并处理
$rawKeywords = explode(' ', trim($currentBook['keywords']));
$targetKeywords = array_filter(array_unique($rawKeywords)); // 去重+过滤空字符串

步骤2:构建查询条件获取推荐图书

你可以用LIKE多条件组合或者正则表达式来匹配包含任意目标关键词的图书:

方式A:使用LIKE OR条件

// 构建多个LIKE条件,用PDO转义防止SQL注入
$likeConditions = [];
foreach ($targetKeywords as $word) {
    $escapedWord = $pdo->quote($word);
    $likeConditions[] = "keywords LIKE '%{$escapedWord}%'";
}
$likeQuery = implode(' OR ', $likeConditions);

// 查询推荐图书,排除当前图书本身
$recommendedBooks = $pdo->query("
    SELECT id, title, keywords 
    FROM books 
    WHERE id != {$currentBookId} 
    AND ({$likeQuery})
")->fetchAll(PDO::FETCH_ASSOC);

方式B:使用正则表达式(更简洁)

// 把关键词转成正则匹配模式,自动转义特殊字符
$regexPattern = implode('|', array_map(function($word) {
    return preg_quote($word, '/');
}, $targetKeywords));

// 执行查询,加i表示忽略大小写
$recommendedBooks = $pdo->query("
    SELECT id, title, keywords 
    FROM books 
    WHERE id != {$currentBookId} 
    AND keywords REGEXP '/{$regexPattern}/i'
")->fetchAll(PDO::FETCH_ASSOC);

方案2:优化数据库结构(推荐长期使用)

如果你的数据量较大,上面的模糊查询可能性能不足,建议把关键词拆分成单独的关联表,这样查询效率更高,也更灵活:

步骤1:创建关键词关联表

CREATE TABLE book_keywords (
    book_id INT NOT NULL,
    keyword VARCHAR(255) NOT NULL,
    FOREIGN KEY (book_id) REFERENCES books(id),
    INDEX idx_keyword (keyword) -- 给关键词加索引提升查询速度
);

之后把原books表的关键词拆分,批量插入到这个关联表中(比如"money investment"拆成两条记录:book_id=1, keyword=money和book_id=1, keyword=investment)。

步骤2:查询推荐图书

通过关联表快速匹配有共同关键词的图书:

// 获取当前图书的所有关键词
$stmt = $pdo->prepare("SELECT keyword FROM book_keywords WHERE book_id = ?");
$stmt->execute([$currentBookId]);
$targetKeywords = $stmt->fetchAll(PDO::FETCH_COLUMN);

// 构建占位符,用预处理防止SQL注入
$placeholders = implode(',', array_fill(0, count($targetKeywords), '?'));
$stmt = $pdo->prepare("
    SELECT DISTINCT b.id, b.title, b.keywords 
    FROM books b
    JOIN book_keywords bk ON b.id = bk.book_id
    WHERE b.id != ? 
    AND bk.keyword IN ({$placeholders})
");
// 执行查询,参数是当前图书ID+目标关键词数组
$stmt->execute(array_merge([$currentBookId], $targetKeywords));
$recommendedBooks = $stmt->fetchAll(PDO::FETCH_ASSOC);

额外优化建议

  • 统一大小写:存储和查询关键词时都转成小写(比如用strtolower()),避免因大小写差异导致匹配失败。
  • 过滤停用词:提前过滤掉"the"、"and"这类无意义的停用词,避免生成无关推荐。
  • 权重排序:可以给匹配的关键词数量加权,匹配越多的图书排越靠前,提升推荐精准度。

内容的提问来源于stack exchange,提问作者ajejoseph22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:41:23