SQL Server全文搜索
我目前正在开发一个具有SQL-Server数据库的应用程序,并且需要进行全文搜索,以使我们能够搜索人的名字。
当前,用户可以在搜索3个不同varchar cols的名称字段中输入a。名,姓,中间名
所以说我有3行以下信息。
1菲利普·弗莱(Phillip J Fry)
2艾米·黄(Amy NULL Wong)
3 Leo NULL黄
如果用户输入" Fry"之类的名称,它将返回第1行。但是,如果他们输入Phillip Fry,Fr或者Phil,他们将一无所获。如果他们搜索Wong,他们将获得第2行和第3行;如果他们搜索Amy Wong,则他们将一无所获。
当前,查询使用的是CONTAINSTABLE,但我已将其与FREETEXTTABLE,CONTAINS和FREETEXT切换,结果没有明显差异。表方法是首选方法,因为它们返回相同的结果但具有排名。
这是查询。
.... @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; ....
有任何想法吗...?为什么此全文搜索无法正常工作?
解决方案
回答
FreeTextTable应该工作。
INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
@SearchString应该包含" Phillip Fry"之类的值(一个长字符串,其中包含所有用空格分隔的查找字符串)。
如果要搜索Fr或者Phil,则应使用星号:Phil *和Fr *
" Phil"正在寻找" Phil"一词。 " Phil *"正在寻找以" Phil"开头的每个单词
回答
如果我们只是在搜索人们的姓名,那么甚至不使用全文本索引也可能是最大利益。当我们有较大的文本字段时,全文索引是有意义的,但是如果我们每个字段最多只处理一个单词,我不确定我们会从全文索引中得到多少额外的收益。等待全文索引重新索引本身,然后再搜索新记录可能是许多问题之一。
我们可以进行如下查询。在空格上分割搜索字符串,并创建一个搜索词列表。
Select FirstName,MiddleName,LastName From person WHERE Firstname like @searchterm1 + '%' or MiddleName like @searchterm1 + '%' or LastName like @searchterm1 + '%' or Firstname like @searchterm2 + '%' etc....
回答
另一种方法可能是将搜索从各个字段中抽象出来。
换句话说,在数据上创建一个视图,该视图会将所有拆分字段(例如名姓)转换为连接字段,即full_name
然后在视图上搜索。这可能会使搜索查询更简单。
回答
感谢回复,我终于能够使它正常工作。包含Biri和Kibbee的部分答案。我需要在字符串中添加*并将其在空格处打散才能工作。所以最后我得到了
.... @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作为全文本的替代方法。