6

我们在下表中添加了自由文本搜索:

| 1 | kayer-meyar | 
| 2 | KA-ME |

但,

select * 
from Names 
where CONTAINS(name, '"ME*"')

仅返回:

| 1 | kayer-meyar |

尽管,

select * 
from Names 
where CONTAINS(name, '"KA*"')

两者都返回:

| 1 | kayer-meyar |
| 2 | KA-ME |

当我们运行时:

select * 
from sys.dm_fts_parser('"KA-ME"', 1033, NULL, 0)

返回:

ka-me
ka
me
4

3 回答 3

3

在搜索和调整您的问题后,我在全文搜索中发现了两个主要错误:

  1. 连字符可能被视为一个分词。它仅| 1 | kayer-meyar |在我使用时返回'"ME*"'。它不返回| 2 | KA-ME |。问题是因为您的条件只允许单词以 (not end withor in a middle)开头ME + at least one character你可以说“那它怎么会 在这个词的中间返回| 1 | kayer-meyar |字符串呢?” me. 好吧,这是因为全文 serach 不将其视为单个单词,而是将其视为两个单独的单词(类似于kayer meyar),因此它满足了 requrement( me*)。同样,在KA-ME它识别为KA ME而不是单个单词的情况下,它也未能满足条件(尽管它带有星号,ME但之后没有额外的字符)
  2. 您是否尝试过重建全文索引?.

现在的解决方案是: 我已经关闭了全文搜索查询的停止列表 使用这个查询(我的表名是MyTable):

ALTER FULLTEXT INDEX ON MyTable SET STOPLIST = OFF

然后运行您的查询。这次你会得到你想要的结果。 在此处输入图像描述

这是我的完整查询:

--CREATE TABLE MyTable
--(
--Id INT IDENTITY(1,1),
--Name varchar(max)  Not Null
--)

---- To see if FULLTEXT installed or not
--SELECT SERVERPROPERTY('IsFullTextInstalled')

---- http://stackoverflow.com/questions/2306825/why-cant-i-create-this-sql-server-full-text-index
---- https://technet.microsoft.com/en-us/library/ms187317.aspx
---- http://stackoverflow.com/questions/2306825/why-cant-i-create-this-sql-server-full-text-index
---- http://stackoverflow.com/questions/2315577/sql-server-2008-full-text-search-on-a-table-with-a-composite-primary-key

--CREATE UNIQUE INDEX ui_MyTable ON MyTable(Id); 
--select name from sysindexes where object_id('MyTable') = id;

--CREATE FULLTEXT CATALOG ft AS DEFAULT; 

--CREATE FULLTEXT INDEX ON MyTable(Name)   
--   KEY INDEX ui_MyTable  
--   WITH STOPLIST = SYSTEM;  
--GO  

--INSERT INTO MyTable(Name) VALUES('kayer-meyar'),('KA-ME');


ALTER FULLTEXT INDEX ON MyTable SET STOPLIST = OFF

select * 
from MyTable 
where CONTAINS(Name, '"ME*"')

select *
from MyTable 
where CONTAINS(Name, '"KA*"')
于 2016-07-06T04:13:23.053 回答
2

您描述的行为是使用系统停用词列表的结果是正确的。这是预期的行为。“我”是一个停用词,存在于系统停用词列表中。数据索引过程默认使用的系统停用词列表。

您可以使用此脚本检查自己:

select * from sys.dm_fts_parser('"KA-ME"', 1033, 0, 0)

这里的第三个参数是停用词列表标识符。当您传递 NULL 时,在解析时不会识别停用词,并且您会看到“完全匹配”类型的“ME”。当您将 0 作为第三个参数传递时,使用系统停用词列表,“ME”将属于“Noise Word”类型。这意味着 SQL Server 不会将其保存到 FTS 索引中进行搜索。

正如 Raihan 提到的,您可以关闭系统停用词列表,但对于我来说,完全关闭停用词是一个太大的锤子,尤其是对于 Azure SQL 数据库,因为您应该支付额外的空间(FTS 索引存储在同一个数据库中内部表)。创建一个新的(较小的)停用词列表并将其用于 FTS 可能是更好的解决方案。

于 2016-07-06T11:39:22.030 回答
0

尝试运行查询: select * from sys.dm_fts_parser('" kayer-meyar"', 1033, NULL, 0)

我在 Kayer-meyar 中不是一个词,你可能不会得到结果。

于 2016-06-28T21:20:51.537 回答