我目前正在开发一个应用程序,我们有一个SQL-Server数据库,我需要进行全文搜索工作,以便我们搜索人名。
目前,用户可以输入一个名称字段来搜索3个不同的varchar cols。第一,最后,中间名
所以说我有3行,其中包含以下信息。
1 - Phillip - J - Fry
2 - Amy - NULL - Wong
3 - Leo - NULL - Wong
如果用户输入诸如'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;
....
任何想法......?为什么这个全文搜索无法正常工作?
答案 0 :(得分:4)
FreeTextTable应该可以工作。
INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
@SearchString应该包含像'Phillip Fry'这样的值(一个长字符串,包含所有以空格分隔的查找字符串)。
如果你想搜索Fr或Phil,你应该使用星号:Phil *和Fr *
''菲尔'正在寻找'菲尔'这个词。 'Phil *'正在寻找以'Phil'开头的每个单词答案 1 :(得分:4)
如果您只是搜索人名,那么甚至不使用全文索引可能符合您的最佳利益。当你有大文本字段时,全文索引是有意义的,但如果你主要处理每个字段一个单词,我不确定你会从全文索引中获得多少额外的东西。在搜索新记录之前等待全文索引重新编制索引可能是许多问题之一。
您可以进行如下查询。在空格上拆分搜索字符串,并创建搜索字词列表。
Select FirstName,MiddleName,LastName From person WHERE Firstname like @searchterm1 + '%' or MiddleName like @searchterm1 + '%' or LastName like @searchterm1 + '%' or Firstname like @searchterm2 + '%' etc....
答案 2 :(得分:3)
感谢回复的家伙,我终于能够让它发挥作用。同时兼有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的列。
感谢您的帮助。
答案 3 :(得分:2)
另一种方法可能是将搜索从各个字段中抽象出来。
换句话说,在数据上创建一个视图,将所有分割字段(如firstname lastname)转换为连续字段,即full_name
然后搜索视图。这可能会使搜索查询更简单。
答案 4 :(得分:2)
您可能需要查看Lucene.net作为全文的替代方法。