我正在使用 Double-Metaphone 在我的数据库中进行模糊搜索。我有一个姓名表,名字和姓氏都已经创建了双变位词条目(并通过触发器更新)。在我的应用程序中,我允许用户按姓氏和/或名字进行搜索。
在处理姓氏和名字时,查询数据库以从双变位索引中获得最佳结果的最佳方法是什么?仅基于姓氏进行查询很容易 - 生成 DM 标签并查询数据库。在第一个和最后一个查询时,我想进行一些微调。
数据库布局类似于以下内容:
tblName
FirstName
LastName
MetaPhoneFN1
MetaPhoneFN2
MetaPhoneLN1
MetaPhoneLN2
申请:[姓] [名]
用户只输入姓氏,或姓氏+ [名字首字母,名字,名字的一部分]的组合。
Lastname: SMITH
FirstName: J or Jo or John or Johnathan
如果我传入“J”作为名字 - 我想要所有匹配“J%”的名称条目。
如果我将“JO”作为名字传递 - 我想要所有匹配“JO%”的名称条目。
如果我传入“JOHN”或“JOHNATHAN”作为名字 - 我想使用 DM
或者也可能是“JOHN%”?
对于名字,我真的很愿意接受这里的建议。我希望结果尽可能好,并返回用户想要的。
查询数据库中姓氏+任何名字组合的最佳方法是什么?这是我到目前为止所获得的样本......我对结果并不完全兴奋:
SELECT *
FROM tblName
WHERE
--There will always be a last name
(MetaPhoneLN1 = @paramMetaPhoneLN1
OR (CASE WHEN @paramMetaPhoneLN2 IS NOT NULL AND MetaPhoneLN2 = @paramMetaPhoneLN2 THEN 1
WHEN @paramMetaPhoneLN2 IS NULL THEN 0
END) = 1)
-- Match Firstname 1
AND (CASE WHEN @paramMetaPhoneFN1 IS NULL THEN 1
WHEN @paramMetaPhoneFN1 IS NOT NULL AND MetaPhoneFN1 = @paramMetaPhoneFN1 THEN 1
WHEN LEN(@paramMetaPhoneFN1) > 1 AND LEN(@paramMetaPhoneFN1) < 4 AND MetaPhoneFN1 LIKE @paramMetaPhoneFN1 + '%' THEN 1
WHEN LEN(@paramMetaPhoneFN1) = 1 THEN 1
END) = 1
-- Match Firstname 2
AND (CASE WHEN @paramMetaPhoneFN2 IS NULL THEN 1
WHEN @paramMetaPhoneFN2 IS NOT NULL AND MetaPhoneFN2 = @paramMetaPhoneFN2 THEN 1
WHEN LEN(@paramMetaPhoneFN2) > 1 AND LEN(@paramMetaPhoneFN2) < 4 AND MetaPhoneFN2 LIKE @paramMetaPhoneFN2 + '%' THEN 1
WHEN LEN(@paramMetaPhoneFN2) = 1 THEN 1
--ELSE 0
END) = 1
AND (CASE WHEN @paramFirstName IS NULL THEN 1
WHEN FirstName LIKE @paramFirstName + '%' THEN 1
--WHEN LEN(@paramMetaPhoneFN1) = 1 AND @paramFirstName IS NOT NULL AND LEN(@paramFirstName) > 1 AND FirstName LIKE @paramFirstName + '%' THEN 1
--ELSE 1
END) = 1
我试图做的是考虑名字的不同变化。然而,我的结果并不是我想要的。
我已经能够在 SQL/C# 等中找到很多 Double Metaphone 的实现,用于 /generating/ Double-Metaphone 值,但是一旦有了这些值,就没有关于如何有效地实际查询数据库的信息。
概括:
当我同时按姓氏和名字搜索时——我想在数据库中查询双变位词匹配只在姓氏上,但是当名字也被传入时,我希望有很大的灵活性..第一个首字母?听上去像 ?等等。我愿意接受建议和 SQL 示例!
更新 1: 当我说我对结果不满意时.. 我的意思是我不确定如何制定查询的 Firstname 部分,以最大化结果。如果我搜索“WILL” - 应该返回什么结果?WILLIAM, WILL, WILBERT .. 但不是 WALKER - 虽然我在这里有什么,WALKER 会被退回,因为 WILL -> FL 和 WALKER 是 [FLKR] 但 WILLIAM 是 [FLM]。如果我只做 DM = DM,那么我什至不会返回 WILLIAM,这就是为什么我首先要做一个 LIKE,如果 DM 长度小于 4。
基本上,我想知道是否有其他人遇到过这个问题,看看其他人提出了什么解决方案。
仅第一个首字母 - 应显示以该首字母开头的所有名字 - 这是我不确定的地方:部分名称 - 所有名字都应该以部分开头吗?[你怎么知道它是否只是一个部分名称?!] 全名 - 应该使用 DM 吗?