全文搜索 - 包含加通配符和单引号
Full text search - Contains plus wildcard and single quote
我有一个 table,其名称字段带有此
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) 使用中性语言 2) 加上全文索引的非索引字表 3) 加上在包含停用词的搜索。
中性语言没有涵盖英语的所有细微差别,因此在索引时它认为 O'neill
是 2 个单独的词 O
和 neill
。然后你的非索引字表认为 O
是一个停用词,所以这个 "word" 不会添加到索引中,只有 neill
是。
在搜索时,搜索引擎通常会忽略多词短语中的停用词。例如,搜索 Contains(*, '"we x people"')
将匹配文本 ...we the people...
,x
和 the
都是停用词,因此会自动 "matching" 彼此。 (我宽松地使用术语 "matching" 是因为搜索引擎不匹配停用词,而是它知道 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) 如果上述解决方案 none 可行,请考虑从搜索短语中删除停用词,或者至少删除姓氏中的 O'
前缀。
我有一个 table,其名称字段带有此
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) 使用中性语言 2) 加上全文索引的非索引字表 3) 加上在包含停用词的搜索。
中性语言没有涵盖英语的所有细微差别,因此在索引时它认为 O'neill
是 2 个单独的词 O
和 neill
。然后你的非索引字表认为 O
是一个停用词,所以这个 "word" 不会添加到索引中,只有 neill
是。
在搜索时,搜索引擎通常会忽略多词短语中的停用词。例如,搜索 Contains(*, '"we x people"')
将匹配文本 ...we the people...
,x
和 the
都是停用词,因此会自动 "matching" 彼此。 (我宽松地使用术语 "matching" 是因为搜索引擎不匹配停用词,而是它知道 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) 如果上述解决方案 none 可行,请考虑从搜索短语中删除停用词,或者至少删除姓氏中的 O'
前缀。