如何有效地搜索可能有多种变体的字符串?

How to tackle efficient searching of a string that could have multiple variations?

我的标题听起来很复杂,其实情况很简单。人们使用 "blackfriday" 等字词在我的网站上进行搜索。

当他们进行搜索时,我的 SQL 代码需要在多个地方(例如 ProductTitleProductDescription 字段中查找以找到该术语。例如:

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

但是,该术语在数据库字段中的显示方式有所不同。它最喜欢在 "Black Friday USA 2015" 这样的单词之间出现 space。那么,如果不通过并在 WHERE 子句中添加更多组合,例如 WHERE ProductTitle LIKE '%Black-Friday%',是否有更好的方法来完成这种模糊搜索?

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

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

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

搜索多个变体时的黑客/解决方法非常重要

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

在仔细研究了所有内容之后,我决定使用 SQL 的 FREETEXT 全文搜索。它不理想,也不准确,但现在必须这样做。

首先我要说 "variations (of a string)" 有点含糊。您可以表示复数、动词时态、同义词、and/or 组合词(或者,忽略两个词之间的空格和标点符号),就像您发布的示例:"blackfriday" vs. "black friday" vs "black-friday".我有一些解决方案,根据您的用例,其中 1 个或多个可能对您有用。

忽略标点符号

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

同义词和组合词

使用 FREETEXT or FREETEXTTABLE for your full text search is a good way to handle synonyms and some matching of combined words (I don't know which ones). You can customize the thesaurus 添加更多组合词,前提是您可以提出这样的列表。

处理任意两个词的组合

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

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