我正在尝试为我的网站创建一个产品搜索,用户可以在其中搜索多种语言的产品,如果没有完全匹配的信息,(希望)获得模糊的搜索结果。
pro_search带有列的表id, pro_id, en, de, es,
fr, it。pro_id列指的是其各自表中产品的ID。en, de, es, fr, it列具有每种产品的各种语言的翻译后的meta。$term 是搜索词。$lang 指用户选择的语言因此,首先,我执行一个基本的“ LIKE” SQL查询以查看是否存在匹配项,如果没有结果,则查询所有产品,并使用similar_text()函数创建一个按其相似性排序的数组
例如,我搜索“衬衫”,如果该产品的元数据仅包含单词“衬衫”,则很好,但如果元数据包含“蓝色品牌的T恤”,则说明性更强,为用户提供了按品牌进行搜索的机会,但意味着搜索将很可能变得模糊,而不是通过LIKESQL查询找到。
这是一种工作,但是我想知道如何改进它,是否有更好的搜索方法,或者人们通常会如何做?我是否应该将meta分为每个单独的关键字,并尝试查看有多少个单词匹配,而不是将术语与整个meta匹配?
$ids = [];
$params = ['%'.$term.'%'];
$sql = "SELECT * FROM pro_search WHERE $lang LIKE ?";
$stmt = DB::run($sql,$params);
$count = $stmt->rowCount();
if($count > 0){
// product search
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$id = $row["pro_id"];
array_push($ids,$id);
}
show_products($ids);
}else{
// product fuzzy search
$sql = "SELECT * FROM pro_search";
$stmt = DB::run($sql);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$id = $row["pro_id"];
$result = $row[$lang];
similar_text($term,$result,$similarity);
$similar_array[$similarity][] = $id;
}
$closest_match = array_keys($similar_array);
rsort($closest_match);
$match_count = count($closest_match);
for($i=0; $i<$match_count; $i++){
foreach($similar_array[$closest_match[$i]] as $id){
array_push($ids,$id);
}
}
show_products($ids);
}
Run Code Online (Sandbox Code Playgroud)
之前我曾问过类似的问题,人们指出了将术语与meta进行比较的不同方法(例如levenshtein),但是我所看到的一切都是在比较两个简单的单词(例如苹果和橘子),而这仅仅是“对于具有数千种产品的现实生活应用程序来说已经足够好了,用户可以搜索几乎所有内容(如中的$term='literally anything';)
关键问题:
您正在寻找带有查询扩展的全文搜索
MySQL 支持使用LIKE运算符和正则表达式进行文本搜索。但是,当文本列很大并且表中的行数增加时,使用这些方法有一些限制:
LIKE语句中的模式或正则表达式中的模式找到确切的文本。LIKE运算符和正则表达式搜索,很难有一个灵活的搜索查询,例如找到描述包含汽车但不包含经典的产品。由于这些限制,MySQL 扩展了一个非常好的特性,即全文搜索。从技术上讲,MySQL 从启用的全文搜索列的单词创建索引,并在该索引上执行搜索。MySQL 使用复杂的算法来确定与搜索查询匹配的行。
为此,将用于搜索的列必须是 TEXT 类型和 FULLTEXT 类型的索引,可以使用ALTER TABLE或CREATE INDEX给出索引,如果您使用 phpMyAdmin 来管理您的数据库,您可以这样做到该表的结构,然后单击该列的操作下的更多并选择全文。
之后,您可以使用 MATCH AGAINST 语法执行搜索。MATCH() 获取要搜索的列。AGAINST 需要一个要搜索的字符串,以及一个指示要执行的搜索类型的可选修饰符。
在某些情况下,用户希望根据他们拥有的知识搜索信息。用户根据他们的经验定义关键字来搜索信息,通常这些关键字太短。
为了帮助用户根据太短的关键字查找信息,MySQL 全文搜索引擎引入了一个称为查询扩展的概念。
查询扩展用于基于自动相关性反馈(或盲查询扩展)扩展全文搜索的搜索结果。从技术上讲,MySQL全文搜索引擎在使用查询扩展时执行以下步骤:
以下示例向您展示了如何搜索产品名称或元数据中至少包含一个词(衬衫 tshirt)的产品。
SELECT * FROM products WHERE MATCH(product_name,product_meta) AGAINST('shirt tshirt' WITH QUERY EXPANSION)
Run Code Online (Sandbox Code Playgroud)
您可以在 MYSQL 文档(答案开头的链接)和此处阅读更多信息
也不要错过How Fine-Tuning MySQL Full-Text Search