我目前正在开发一个具有SQL-Server数据库的应用程序,并且需要进行全文搜索,以使我们能够搜索人的名字。
当前,用户可以在搜索3个不同varchar cols的名称字段中输入a。名,姓,名
所以说我有3行以下信息。
1-菲利普-J-弗莱
2-艾米-空-黄
3-狮子座-空-黄
如果用户输入" Fry"之类的名称,它将返回第1行。但是,如果他们输入Phillip Fry或Fr或Phil,他们将一无所获。。我不明白为什么这样做。如果他们搜索Wong,他们将获得第2行和第3行;如果他们搜索Amy Wong,则他们将一无所获。
当前,查询使用的是CONTAINSTABLE,但我已将其与FREETEXTTABLE,CONTAINS和FREETEXT切换,结果没有任何明显的不同。首选table方法,因为它们返回相同的结果但具有排名。
这是查询。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
SET @SearchString = '"'+@Name+'"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;
.... |
有任何想法吗...?为什么此全文搜索无法正常工作?
如果您只是在搜索人员的姓名,那么甚至不使用全文本索引也可能是您的最大利益。当您具有较大的文本字段时,全文索引是有意义的,但是如果您每个字段最多只处理一个单词,我不确定您会从全文索引中得到多少额外的收益。等待全文索引重新索引本身,然后再搜索新记录可能是许多问题之一。
您可以进行如下查询。在空格上分割您的搜索字符串,并创建一个搜索词列表。
1 2 3 4 5 6 7 8
| Select FirstName,MiddleName,LastName
From person
WHERE
Firstname like @searchterm1 + '%'
or MiddleName like @searchterm1 + '%'
or LastName like @searchterm1 + '%'
or Firstname like @searchterm2 + '%'
etc.... |
FreeTextTable应该工作。
1
| INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) |
@SearchString应该包含" Phillip Fry"之类的值(一个长字符串,其中包含所有用空格分隔的查找字符串)。
如果要搜索Fr或Phil,则应使用星号:Phil *和Fr *
" Phil"正在寻找" Phil"一词。" Phil *"正在寻找以" Phil"开头的每个单词
感谢您的回复,我终于能够使它正常工作。包含Biri和Kibbee的部分答案。我需要在字符串中添加*并将其在空格处分开才能工作。所以最后我得到了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
--Added this line
SET @SearchString = REPLACE(@Name, ' ', '*" OR"*')
SET @SearchString = '"*'+@SearchString+'*"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;
.... |
在搜索更多字段时,我只是将其简化为问题,对此感到抱歉,我认为这不会影响答案。实际上,它搜索的是具有昵称csv的列以及notes列。
谢谢您的帮助。
您可能想查看Lucene.net作为全文本的替代方法。
另一种方法可能是将搜索从各个字段中抽象出来。
换句话说,在您的数据上创建一个视图,该视图会将所有拆分字段(例如名姓)转换为连接字段,即full_name
然后在视图上搜索。这可能会使搜索查询更简单。