我有一个带有此
的名称字段的表格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*"' )
这是为什么?
我正在为我的搜索字词使用解析器,这是添加通配符*
我查了一些关于逃离'
的网站,但是我没有找到任何涉及此内容的网站。
先谢谢
答案 0 :(得分:6)
问题是由于1)使用中性语言2)加上全文索引的停止列表3)以及在包含停用词的搜索中使用通配符时的意外行为。
中性语言并未涵盖英语的所有细微差别,因此在索引时,它会将O'neill
视为2个单独的单词O
和neill
。然后,您的停用列表会将O
视为停用词,因此此“字”不会添加到索引中,只会neill
为。
在搜索时,搜索引擎通常忽略多词短语中的停用词。例如,搜索Contains(*, '"we x people"')
将匹配文字...we the people...
,x
和the
两者都是停用词,从而自动“匹配”彼此。 (我松散地使用术语“匹配”,因为搜索引擎不匹配停用词,而是知道people
与we
相距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'
前缀。