在SQL Server上逐字使用SOUNDEX()

时间:2009-12-17 17:41:50

标签: sql sql-server soundex

这是我的问题。例如,我有一个表 Products ,其中包含一个字段 Name

Products
ID | Name | ..
1  | "USB Key 10Go"
2  | "Intel computer"
3  | "12 inches laptop computer"
...

我目前正在为iPhone网络应用程序实现一个简单的搜索引擎(SQL Server和ASP .NET,C#),我想使用SOUNDEX() SQL Server功能。

问题是,我无法在名称字段上直接使用SOUNDEX。 (这是无关紧要的,因为名称中有几个单词。)我想将SOUNDEX函数应用于 Name 字段中的每个单词,然后查看它们是否匹配研究过的关键字。

如果有人知道如何做到这一点,那就太棒了。

5 个答案:

答案 0 :(得分:5)

与使用Soundex相比,您可能最好不要计算两个弦之间的Levenshtein距离。请参阅the Wikipedia article on Levenshtein distance

Levenshtein距离算法here的TSQL实现。

分享并享受。


编辑03-May-2012

自从编写我的原始响应以来,我已经了解到Oracle在UTL_MATCH包中包含了Levenshtein距离和其他几个“字符串相似性”函数,我相信这是数据库的标准部分。文档here。也许与原始帖子(适用于SQL Server)没有直接关系,但可能很有用,因为许多商店使用多个数据库。

答案 1 :(得分:4)

您是否研究过SQL Server中的全文搜索功能?我知道这不是你要求的。只是SOUNDEX()函数用于查找类似的SOUNDING名称(EX:SMITH和SMYTHE声音相同)。然而,在搜索引擎中,单词发声的方式与搜索单词本身相比不那么重要。全文搜索还允许您使用同义词(允许您指定在应用程序上下文中表示相同内容的某些单词),并在搜索过程中自动考虑这些单词。

有关SQL Server中的全文搜索的详细信息,请查看这些页面:

Introduction to Full-Text Search

CONTAINS

CONTAINSTABLE

FREETEXT

FREETEXTTABLE

答案 2 :(得分:1)

如果你必须在RDBMS中完成所有工作,如果它是一个选项,UDF将是最好的。

否则,您可以使用此技术至少使用PARSENAME单独对前四个单词进行索引:

来自How do I split a string so I can access item x?

PARSENAME(REPLACE('12 inches laptop computer', ' ', '.'), 1)  --return computer
PARSENAME(REPLACE('12 inches laptop computer', ' ', '.'), 2)  --return laptop
...

然而:以这种方式使用PARSENAME是一个黑客,一个严重的限制是它最多只能工作4个部分。如果有5个或更多单词,PARSENAME将返回NULL,因此您必须使用条件检查并优雅地降级。

这是一个简化的例子(同样,没有NULL检查)

SELECT *
FROM Products 
WHERE SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 4))
  OR SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 3))
  OR SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 2))
  OR SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 1))

答案 3 :(得分:1)

SOUNDEX可能非常适合你的紫癜,但请记住,除英国或美国英语口语外,它可能无法提供其他任何好的结果!它甚至可以用于德语语音口语,但它不适用于任何其他语言。

答案 4 :(得分:1)

您可以尝试存储与连字符连接的每个单词的metaphone。 EG stored_metaphone字段可以包含类似'-AKTRF-SPLS-'的内容。然后构建一个这样的查询:

$where = '(';
$search_sql = array();
$search_terms = explode(' ',$search);
foreach ($search_terms as $term) {
    $search_sql[] = "`stored_metaphone` LIKE '%-".metaphone($term)."-%'";
}
$where .= implode(' OR ',$search_sql);
$where .= ')';

注意,这只是查询的WHERE部分。

据我所知,metaphone仅适用于英语。上面的sql在许多站点上工作得很好。