希望我不再重复这个问题。我在这里和谷歌做了一些搜索,然后再在这里发布。
我正在使用启用了全文本的SQL Server 2008R2运行eStore。
我的要求
有一个产品表,其中包含该产品适合的产品名称,OEM代码,型号。所有内容均为文字。
我创建了一个名为TextSearch的新列。这具有此产品适用的产品名称,OEM代码和型号的串联值。这些值以逗号分隔。
当客户输入关键字时,我们在TextSearch列上运行搜索以匹配产品。请参阅下面的匹配逻辑。
我使用的是混合全文,通常喜欢进行搜索。这给出了更相关的结果。在临时表中执行的所有查询均返回。
匹配逻辑
运行以下SQL以获取全文的相关产品。但是@Keywords将被预处理。说“ CLC 2200”将更改为“ CLC * AND 2200 *”
从dbo.product的位置选择ID(TextSearch,@ Keywords)
另一个查询将使用正常的赞运行。因此,“ CLC 2200”将被预处理为“像%clc%这样的TextSearch和像%2200%这样的TextSearch”。这仅仅是因为全文搜索不会在关键字之前搜索模式。例如,它不会返回“ pclc 2200”。
从dbo.Product中选择ID,其中TextSearch如'%clc%'和TextSearch如'%2200%'
如果第1步和第2步未返回任何记录,则将执行以下搜索。我对值135进行了微调,以返回更多相关记录。
从dbo.Product中选择p.id,作为p内联接FREETEXTTABLE(product,TextSearch,@ Keywords)作为p.Id = r。[r] r.RANK> 135
上述所有组合都能以合理的速度正常运行,并返回关键字的相关产品。
但是,当根本没有找到产品时,我正在寻求进一步的改进。
假设客户寻找“ CLC 2200npk”而该产品不存在,我需要在“ CLC 2200”旁边显示下一个。
到目前为止,我尝试使用Soundex()函数。购买TextSearch列中每个单词的计算soundex值,并与关键字的soudex值进行比较。但这会返回太多的记录,而且速度也很慢。
例如,“ CLC 2200npk”将返回“ CLC 1100”等产品。但这并不是一个好结果。由于它不接近CLC 2200npk
还有一个很好的here。但这使用CLR函数。但是我无法在服务器上安装CLR功能。
所以我的逻辑应该是
如果未找到“ CLC 2200npk”,则显示“ CLC 2200”附近的内容
如果未找到“ CLC 2200”,则在“ CLC 1100”旁边显示下一个关闭
问题
是否可以按照建议进行匹配?
如果我需要进行拼写校正和搜索,那是什么好方法?我们所有的产品清单都是英文的。
是否有UDF或SP可以匹配我的建议的文本?
谢谢。
最佳答案
特定于域的快速解决方案可能是使用SOUNDEX和2个字符串之间的数字距离来计算字符串相似度。仅当您具有很多产品代码时,这才真正有用。
使用如下所示的简单UDF,您可以从字符串中提取数字字符,以便可以从“ CLC 2200npk”中获得2200,从“ CLC 1100”中获得1100,因此现在可以基于每个输入的SOUNDEX输出确定紧密度以及每个输入的数字部分的紧密度。
CREATE Function [dbo].[ExtractNumeric](@input VARCHAR(1000))
RETURNS INT
AS
BEGIN
WHILE PATINDEX('%[^0-9]%', @input) > 0
BEGIN
SET @input = STUFF(@input, PATINDEX('%[^0-9]%', @input), 1, '')
END
IF @input = '' OR @input IS NULL
SET @input = '0'
RETURN CAST(@input AS INT)
END
GO
就通用算法而言,根据数据集的大小和性能要求,有几种方法可以帮助您获得不同程度的成功。 (两个链接都有可用的TSQL实现)
Double Metaphone-这种算法将以比速度更快的代价提供比soundex更好的匹配效果,尽管它确实对拼写校正非常有用。
Levenshtein Distance-这将计算将一个字符串转换为另一个字符串(例如,从“ CLC 2200npk”到“ CLC 2200”)需要多少次按键,而从“ CLC 2200npk”到“ CLC 1100”是5次。
Here是一篇有趣的文章,将两种算法结合使用,可能会给您一些想法。
希望其中一些有所帮助。
编辑:Here是一个更快的部分Levenshtein Distance实现(请阅读它不会返回与正常结果完全相同的结果的帖子)。在我的125000行的测试表上,它的运行时间为6秒,而我链接到的第一个表则为60秒。