首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >PHP / SQL -改进搜索功能/模糊搜索

PHP / SQL -改进搜索功能/模糊搜索
EN

Stack Overflow用户
提问于 2019-03-14 00:53:59
回答 3查看 2.6K关注 0票数 5

我正在尝试为我的网站创建一个产品搜索,其中用户可以搜索多种语言的产品,并(希望)得到模糊搜索结果,如果没有精确匹配。

  • 我有一个包含id, pro_id, en, de, es, fr, it列的pro_search表。
  • pro_id列引用各自表中产品的id。在搜索列中,每种产品的翻译后的元都以不同的语言表示。meta is languages.
  • The spaces
  • $term分隔的关键字is en, de, es, fr, it term.
  • $lang指的是用户选择的语言

因此,首先我执行一个基本的'LIKE‘SQL查询,看看是否有匹配,如果没有结果,我将查询所有产品,并使用similar_text()函数创建一个按相似度排序的数组

例如,我搜索‘衬衫’,如果这个产品的元数据只包括单词‘衬衫’,这是很好的,但如果元数据包括‘蓝色品牌T恤’,这是更具描述性的,并为用户提供了一个按品牌搜索的机会,但这意味着搜索很可能会变得模糊,而不是通过LIKE SQL查询找到。

这在某种程度上是可行的,但我想知道如何改进这一点,有没有更好的搜索方式,或者人们通常是怎么做的?我是否应该将元划分为每个单独的关键字,并尝试查看有多少个单词匹配,而不是将术语与整个元匹配?

代码语言:javascript
复制
    $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);
    }

我以前问过类似的问题,人们给我指出了将该术语与元进行比较的不同方法(如levenshtein),但我看到的所有东西都是比较两个简单的单词(如苹果和橙子),这对于有成千上万种产品的现实应用程序来说并不够好,用户可以搜索任何东西(如在$term='literally anything';中)。

关键问题:

  • 我的meta应该只有产品名称还是多个相关关键字(关键字太多意味着单个词与整体不太相似)?
  • 如果元中有多个关键字,我是否应该采用每个单独的关键字并将其与搜索词进行比较?
  • 还可以针对单个产品使用负面关键字。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-04-12 07:02:10

您正在寻找Full-Text Searches WITH QUERY EXPANSION

通过使用LIKE运算符和正则表达式,MySQL支持文本搜索。但是,当文本列很大并且表中的行数增加时,使用这些方法会有一些限制:

  • 性能: MySQL必须扫描整个表,才能根据LIKE语句中的模式或常规expressions.
  • Flexible搜索中的模式查找准确的文本:使用LIKE运算符和正则表达式搜索,很难有灵活的搜索查询,例如,查找其描述包含汽车但不包含排名的产品:无法指定结果集中的哪一行与搜索术语更相关。

由于这些限制,MySQL扩展了一个非常好的特性,即所谓的全文搜索。从技术上讲,MySQL从启用的全文搜索列的单词创建索引,并对该索引执行搜索。MySQL使用一种复杂的算法来确定与搜索查询匹配的行。

为此,将用于搜索的列必须是文本类型和全文类型的索引,索引可以使用ALTER TABLECREATE INDEX给出,如果您使用phpMyAdmin来管理数据库,您可以通过转到该表的结构来执行此操作,然后在该列的操作下单击更多并选择全文。

在此之后,您可以使用匹配语法执行搜索。MATCH()获取要搜索的列。使用要搜索的字符串和一个可选修饰符,该修饰符指示要执行的搜索类型。

具有查询扩展功能的全文搜索:

在某些情况下,用户希望基于他们所拥有的知识来搜索信息。用户使用他们的经验来定义关键字来搜索信息,通常这些关键字太短。

为了帮助用户根据过短的关键字查找信息,MySQL全文搜索引擎引入了查询扩展的概念。

查询扩展用于扩大基于自动相关反馈的全文搜索的搜索结果(或盲查询扩展)。从技术上讲,MySQL全文搜索引擎在使用查询扩展时会执行以下步骤:

  • 首先,全文搜索引擎查找与搜索结果匹配的所有行。MySQL全文搜索引擎检查搜索结果中的所有行,并找到相关的关键字。

根据相关的单词而不是用户提供的原始关键字再次执行搜索。MySQL

下面的示例展示了如何搜索其产品名称或meta至少包含一个单词的产品(衬衫、T恤)。

代码语言:javascript
复制
SELECT * FROM products WHERE MATCH(product_name,product_meta) AGAINST('shirt tshirt' WITH QUERY EXPANSION)

你可以在MYSQL文档(答案开头的链接)和here中阅读更多信息。

也不要错过How Fine-Tuning MySQL Full-Text Search

票数 5
EN

Stack Overflow用户

发布于 2019-04-11 04:03:05

如果你还在设计这个系统,你可以有一点不同的想法。在搜索方面,只需执行精确搜索,并按照前面的建议在db中执行,因为这要快得多-但“从每次交互中学习”。

  • 用户输入一些术语
  • ,如果搜索结果很好,您可以进行精确搜索。
  • ,如果不是,则对输入的术语的每个部分进行模糊搜索。还是找不到,你做soundex。你正在尝试寻找一些东西!但是向用户提供一个很长的列表来过滤through.
  • Eventually用户选择一个。一旦他们这样做了,您就将他们输入的术语添加到他们选择的产品中。

所以基本的想法是,你可以从每个互动中学习,丰富你的搜索集。此外,当术语是用户,并且用户实际点击您的项目时,随着您对术语与产品关联的信心的提高,您将对该术语与产品的关联进行计数。

类似地,当你呈现一个选项时,用户应该能够很容易地说“不是这个”,然后引导他们通过预先选择的项目层次结构,最终当他们选择一个时,你将他们的搜索词保存到产品中。

因此,在几个月内,如果你获得了足够的用户,你就会有一个丰富的有机搜索术语数据集,用于你的产品类别,每个术语的置信度水平。

票数 3
EN

Stack Overflow用户

发布于 2019-04-05 17:17:49

您可以在sql中使用SOUNDEX

代码语言:javascript
复制
SELECT * FROM users 
           WHERE SOUNDEX(job) 
LIKE CONCAT('%',SUBSTRING(SOUNDEX('Manual worker'),2),'%');

Manual worka这样的东西将会起作用。您只需调整该值(当前为2)即可满足您的需要。

我看到您已经尝试过Levenshtein算法,但您应该注意this adaptation (它也与UTF-8字符串兼容)

对我来说,soundex更有效,这取决于你的用户如何与你的应用程序交互。

但正如评论中所说,像ElasticSearchAlgolia这样的第三方可以更有效率。

我从来没有用过它,因为公司不允许我们使用第三方软件。这就是为什么我尝试了LevenstheinSoundex

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55147321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档