【问题标题】:How to tackle efficient searching of a string that could have multiple variations?如何有效地搜索可能有多种变体的字符串?
【发布时间】:2016-02-28 18:24:21
【问题描述】:

我的标题听起来很复杂,但情况很简单。人们使用诸如“blackfriday”之类的术语在我的网站上进行搜索。

当他们进行搜索时,我的 SQL 代码需要在各个位置(例如 ProductTitleProductDescription 字段)查找该术语。例如:

SELECT * 
FROM dbo.Products 
WHERE ProductTitle LIKE '%blackfriday%' OR 
ProductDescription LIKE '%blackfriday%'

但是,该术语在数据库字段中的显示方式有所不同。它最喜欢出现在诸如“Black Friday USA 2015”之类的单词之间的空格。那么在不通过WHERE 子句(例如WHERE ProductTitle LIKE '%Black-Friday%')添加更多组合的情况下,有没有更好的方法来完成这种模糊搜索?

我在上述字段上启用了全文搜索,但是当我使用CONTAINS 子句时,它真的不是那么好。当然,其他术语可能没有这个例子那么简洁。

【问题讨论】:

  • 可能有一种更简洁、更简单的方法,但我的第一个想法是使用 REPLACE 来消除搜索词和列中的标点符号和空格。
  • FREETEXT (正如您在回答中提到的)是处理单词变化的最佳解决方案。但它不会帮助匹配像blackfriday 这样的组合词,除了可能 通常组合词,如dogcatcher,尽管我什至不确定它是否可以做到这一点。让我知道是否需要处理 任何 组合词,我可以提供帮助。
  • @Keith 是的,请 Keith,它的组合词让我很生气!如果您有任何建议,我将非常感谢

标签: sql sql-server search full-text-search sql-server-2014


【解决方案1】:

我首先应该说“(字符串的)变体”有点含糊。您可以表示复数、动词时态、同义词和/或组合词(或忽略两个词之间的空格和标点符号),例如您发布的示例:“blackfriday”与“black friday”与“black-friday”。我有一些解决方案,其中一个或多个可能对您有用,具体取决于您的用例。

忽略标点符号

全文搜索已经忽略标点符号并将它们与空格匹配。所以black-friday 将匹配black friday,无论是使用FREETEXT 还是CONTAINS。但它不会匹配blackfriday

同义词和组合词

使用FREETEXTFREETEXTTABLE 进行全文搜索是处理同义词和一些 组合词匹配的好方法(我不知道是哪些)。你可以customize the thesaurus添加更多的组合词,假设你想出这样一个列表是可行的。

处理任意 2 个单词的组合

也许您的用例要求您匹配格式不佳的文本或主题标签。在这种情况下,我有几个想法:

  • 使用字典编写全文查询以涵盖每个单词组合。例如,您的数据层可以将black friday 的搜索重写为CONTAINS(*, '"black friday" OR "blackfriday"')。这可能必须变得复杂,例如black friday treehouse 必须是("black friday" OR "blackfriday") AND ("treehouse" OR "tree house")?您需要一本字典才能确定“树屋”由 2 个单词组成,因此可以拆分。
  • 如果对要搜索的词使用字典不实用(我不知道为什么,可能是首字母缩略词或新模因),您可以创建一个长查询来涵盖每个字母组合。所以搜索do-re-mi 可能是"do re mi" OR "doremi" OR "do remi" OR "dore mi" OR "d oremi" OR "d o remi" ...。是的,它会有很多组合,但令人惊讶的是,它可能会运行得很快,因为全文在索引中查找单词的效率很高。

【讨论】:

    【解决方案2】:

    在查看完所有内容后,我决定使用 SQL 的FREETEXT 全文搜索。它并不理想,也不准确,但现在必须这样做。

    【讨论】:

      【解决方案3】:

      如果搜索多个变体非常重要,则黑客/解决方法。

      1. 定义数据库中的哪些字段是可搜索的(例如ProductTitleProductDescription
      2. 在将这些字段保存到数据库之前,请用占位符替换每个空格(或连续空格,例如 "%"
      3. 使用占位符在数据库中搜索变体匹配
      4. 在您的网站上显示这些字段时执行相反的过程(即用空格替换占位符)
      5. 或者,您可以为您的用户启用正则表达式匹配(这意味着他们可以明确定义正则表达式,或者让您的应用根据他们的搜索词构建一个正则表达式)。但这样做会更慢,而且可能容易出错

      【讨论】:

        【解决方案4】:

        我的回答可能不够充分,但您是否有以下查询无法解决的情况。

        SELECT * 
        FROM dbo.Products 
        WHERE ProductTitle LIKE '%black%friday%' OR 
        ProductDescription LIKE '%black%friday%'
        

        【讨论】:

        • 是的,因为字符串本身就是一个参数,我不知道字符串实际上是什么
        猜你喜欢
        • 2011-08-28
        • 2017-09-21
        • 1970-01-01
        • 1970-01-01
        • 2020-12-21
        • 2013-10-10
        • 1970-01-01
        • 2016-08-23
        • 2018-08-05
        相关资源
        最近更新 更多