代码之家  ›  专栏  ›  技术社区  ›  Paddy Hallihan

菲律宾比索。/SQL-改进搜索特性/模糊搜索

  •  0
  • Paddy Hallihan  · 技术社区  · 7 年前

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

    • pro_search 具有列的表 id, pro_id, en, de, es, fr, it .
    • pro_id 列是指
    • 这个 en, de, es, fr, it 列已翻译
    • 元只是用空格分隔的关键字
    • $term 是搜索词。
    • $lang 指用户选择的语言

    因此,首先我执行一个基本的“LIKE”SQL查询,看看是否有匹配项,如果没有结果,我将查询所有产品,并使用 similar_text()

    例如,我搜索“shirt”如果这个产品的meta只包含“shirt”这个词就可以了,但是如果meta包含“blue branded tshirt”,这就更具描述性了,用户可以按品牌搜索,但这意味着搜索很可能会变得模糊,而不是用 LIKE SQL查询。

    这是一种工作,但我想知道如何改进,有没有更好的搜索方法或人们通常如何做?我是否应该将元分解为每个单独的关键字,并尝试查看有多少个词匹配,而不是将该词与整个元匹配?

        $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);
        }
    

    我以前也问过类似的问题,人们给我指出了将这个词与meta(比如levenshtein)进行比较的不同方式,但我所看到的一切都是比较两个简单的词(如苹果和橘子),这对于一个拥有数千种产品的现实应用程序来说是不够的,用户可以搜索任何东西(如 $term='literally anything'; )

    关键问题:

    • 我的meta应该只有产品名还是多个相关的 关键字(太多的关键字意味着单个单词不太相似 整体而言)?
    • 如果元中有多个关键字,我应该 获取每个单独的关键字并将其与搜索进行比较 任期?
    • 也可能有否定的关键字 个别产品。
    0 回复  |  直到 7 年前
        1
  •  3
  •   user2203703    7 年前

    你在找 Full-Text Searches WITH QUERY EXPANSION

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

    • 性能:MySQL必须扫描整个表以根据 就像 正则表达式中的语句或模式。
    • 灵活搜索:使用 就像
    • 相关性排名:无法指定结果集中的哪一行与搜索词更相关。

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

    ALTER TABLE 或 CREATE INDEX 如果使用phpMyAdmin管理数据库,可以转到该表的结构,然后在该列的Action下单击More并选择Fulltext。

    之后,您可以使用MATCH-AGAINST语法执行搜索。MATCH()获取要搜索的列。获取要搜索的字符串和指示要执行的搜索类型的可选修饰符。

    使用查询扩展进行全文搜索:

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

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

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

    • 首先,MySQL全文搜索引擎查找与搜索查询匹配的所有行。
    • 其次,它检查搜索结果中的所有行并找到相关的单词。

    下面的示例演示如何搜索其产品名称或meta至少包含一个单词(shirt tshirt)的产品。

    SELECT * FROM products WHERE MATCH(product_name,product_meta) AGAINST('shirt tshirt' WITH QUERY EXPANSION)
    

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

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

        2
  •  3
  •   Saad Ahmad    7 年前

    如果你还在设计这个系统的话,你的想法可能会有点不同。在搜索方面,只需做准确的搜索,并在数据库中做,因为这是更快的-但“从每个互动学习”。

    • 某些术语中的用户类型
    • 最终用户选择一个。一旦他们这样做,您就将他们输入的术语添加到他们选择的产品中。

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

    因此,在几个月内,如果你有足够的用户,你将有一个丰富的有机搜索词数据集为您的产品类别与每个术语的信心水平。

        3
  •  2
  •   Atnaize    7 年前

    SOUNDEX 在sql中

    SELECT * FROM users 
               WHERE SOUNDEX(job) 
    LIKE CONCAT('%',SUBSTRING(SOUNDEX('Manual worker'),2),'%');
    

    像这样的事情 Manual worka 2 )以满足你的需要。

    this adaptation (也与UTF-8字符串兼容)

    就我而言,soundex效率更高,这将取决于用户将如何与应用程序交互。


    ElasticSearch 或 Algolia 会更有效率。

    我从未使用过它,因为公司不允许我们使用第三方软件。所以我两个都试了 左旋戊烯 Soundex公司

    推荐文章