关于搜索:SQL Server全文搜索

关于搜索:SQL Server全文搜索

SQL Server Full Text Searching

我目前正在开发一个具有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

然后在视图上搜索。这可能会使搜索查询更简单。


推荐阅读