全文搜索 - 包含加上通配符和单引号

时间:2015-09-04 18:55:09

标签: sql-server full-text-search wildcard wordbreaker

我有一个带有此

的名称字段的表格
Test O'neill 123

如果我使用

SELECT  *
    FROM    table F
    WHERE   CONTAINS ( F.*, '"Test O''neill 123"' )

它工作正常,但如果我使用通配符*,我没有结果。

SELECT  *
    FROM    table f
    WHERE   CONTAINS ( F.*, '"Test O''neill 123*"' )
这是为什么? 我正在为我的搜索字词使用解析器,这是添加通配符*

我查了一些关于逃离'的网站,但是我没有找到任何涉及此内容的网站。

先谢谢

1 个答案:

答案 0 :(得分:6)

问题是由于1)使用中性语言2)加上全文索引的停止列表3)以及在包含停用词的搜索中使用通配符时的意外行为。

中性语言并未涵盖英语的所有细微差别,因此在索引时,它会将O'neill视为2个单独的单词Oneill。然后,您的停用列表会将O视为停用词,因此此“字”不会添加到索引中,只会neill为。

在搜索时,搜索引擎通常忽略多词短语中的停用词。例如,搜索Contains(*, '"we x people"')将匹配文字...we the people...xthe两者都是停用词,从而自动“匹配”彼此。 (我松散地使用术语“匹配”,因为搜索引擎不匹配停用词,而是知道peoplewe相距1个字。)

因此,您可能希望通配符搜索Contains(*, '"we the people*"')也找到匹配项,但使用停止列表时不会。如果不是搜索词组中的停用词the,或者the不被视为停用词,则搜索会正常运行。我真的无法解释这种行为,但我怀疑它与单词位置的计算方式有关。我也怀疑这不是预期的行为。

回到您的情况,Contains(*, '"Test O''neill 123"')会找到匹配,但通配符搜索Contains(*, '"Test O''neill 123*"')却没有。 (你甚至可以简化搜索到Contains(*, '"O''neill*"'),你会发现它仍然没有找到匹配。)停用词O与通配符的组合遇到了我在上一次解释的问题段。这是你问题中陈述的问题的关键。

解决方案从最有效到最不有效但可能更实用的案例:

1)将全文索引的语言更改为英语并重新编制索引。这将导致O'neill被视为1个单词,因此您将避免我解释的奇怪的通配符行为。您可以通过SQL Server Management Studio更改全文索引属性中的语言,也可以按如下方式删除并重新创建索引:

ALTER FULLTEXT INDEX ON MyTable DROP (Column1) 
GO
ALTER FULLTEXT INDEX ON MyTable ADD (Column1 LANGUAGE [English])
-- repeat for each column in the index

2)如果您需要继续使用中性语言,请考虑从停止列表中删除O并重新编制索引。

ALTER FULLTEXT STOPLIST MyStoplist DROP 'o' LANGUAGE 'Neutral';

3)如果您不需要,请不要使用停止列表。

ALTER FULLTEXT INDEX ON MyTable SET STOPLIST = OFF

4)如果以上解决方案都不实用,请考虑从搜索短语中移除停用词,或至少删除姓氏中的O'前缀。