Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL CONTAINSTABLE-意外结果_Sql_Sql Server_Full Text Search_Contains_Stop Words - Fatal编程技术网

SQL CONTAINSTABLE-意外结果

SQL CONTAINSTABLE-意外结果,sql,sql-server,full-text-search,contains,stop-words,Sql,Sql Server,Full Text Search,Contains,Stop Words,我有一个带有一些记录的表格程序,如果使用LIKE或CONTAINSTABLE,结果会不同 CREATE TABLE Programs ( ID varchar(255) NOT NULL PRIMARY KEY, Title varchar(255) NOT NULL ); Insert INTO Programs VALUES ('1', '5 Horas em Islamabad'), ('2','Gus Melhoras" Melhora'), ('3',

我有一个带有一些记录的表格程序,如果使用LIKE或CONTAINSTABLE,结果会不同

CREATE TABLE Programs (
    ID varchar(255) NOT NULL PRIMARY KEY,
    Title varchar(255) NOT NULL
);

Insert INTO Programs VALUES 
('1', '5 Horas em Islamabad'), 
('2','Gus Melhoras" Melhora'), 
('3', '13 Horas - Os Soldados Secretos de Benghazi'),
('4','72 Horas de Medo'), 
('5','As Primeiras 48 Horas')

SELECT distinct Title FROM Programs WHERE Title LIKE '%Horas%'

SELECT ID, Title, KEY_TBL.RANK  
FROM Programs AS DocTable   
INNER JOIN CONTAINSTABLE(Programs, Title, 'Horas') AS KEY_TBL  
  ON DocTable.ID = KEY_TBL.[KEY]  
WHERE KEY_TBL.RANK > 0  
ORDER BY KEY_TBL.RANK DESC;  
使用LIKE我有5个结果

ID  Title
1   5 Horas em Islamabad
2   Gus Melhoras" Melhora
3   13 Horas - Os Soldados Secretos de Benghazi
4   72 Horas de Medo
5   As Primeiras 48 Horas
通过ContainsTable我有两个结果

ID  Title                   RANK
4   72 Horas de Medo        32
5   As Primeiras 48 Horas   32
我理解为什么标题为“Gus Melhoras”Melhora“的记录没有返回,因为没有“Horas”这个词。 但记录“伊斯兰堡5小时”和“班加西13小时-索尔达多秘笈”包含“小时”一词,不再返回

有人能解释为什么会发生这种情况,并能帮助我吗

我的数据库管理系统是Microsoft SQL Server

编辑

在我的例子中,我在“巴西人”中定义了“分词语言”。如果我改为“英语”,则正确返回4项

我搜索的单词“Horas”在英语中是“Hours”。但如果我添加新记录,标题为“13小时在伊斯兰堡”,并按单词“Hours”搜索,记录将返回

有人知道为什么用巴西语或葡萄牙语会有这种行为吗

此外,在西班牙语中,“Horas”与“Horas”是同一个词,如果我将“分词器语言”更改为西班牙语,则返回4项

EDIT2

使用Marin中@Randy发送的查询,我使用葡萄牙语进行测试

SELECT s.stopword, l.name 
FROM sys.fulltext_system_stopwords s 
JOIN sys.fulltext_languages l ON l.lcid = s.language_id 
WHERE l.lcid = 2070 -- portuguese
当执行查询以查找精确匹配项时

SELECT occurrence, special_term, left(display_term, 20) as [display_term] 
FROM sys.dm_fts_parser ('"5 Horas em Islamabad"', 2070, 0, 0); -- portuguese

这是与巴西语言相同的结果,尽管有数字停止词

dmv sys.dm_fts_解析器显示了在有或没有停止列表或重音的情况下如何为不同语言解析短语

SET NOCOUNT ON

--select * from sys.syslanguages

SELECT occurrence, special_term, left(display_term, 20) as [display_term] 
FROM sys.dm_fts_parser ('"5 Horas em Islamabad"', 1033, 0, 0); -- english

SELECT occurrence, special_term, left(display_term, 20) as [display_term] 
FROM sys.dm_fts_parser ('"5 Horas em Islamabad"', 1046, 0, 0); -- brazilian

SELECT occurrence, special_term, left(display_term, 20) as [display_term] 
FROM sys.dm_fts_parser ('"5 Horas em Islamabad"', 3082, 0, 0); -- spanish

occurrence  special_term     display_term
----------- ---------------- --------------------
1           Noise Word       5
1           Noise Word       nn5
2           Exact Match      horas
3           Exact Match      em
4           Exact Match      islamabad

occurrence  special_term     display_term
----------- ---------------- --------------------
1           Exact Match      tt24050000
1           Exact Match      5 horas
1           Exact Match      tt24170000
2           Noise Word       em
3           Exact Match      islamabad

occurrence  special_term     display_term
----------- ---------------- --------------------
1           Noise Word       5
1           Noise Word       nn5
2           Exact Match      horas
3           Exact Match      em
4           Exact Match      islamabad

“5”在巴西语中不是一个干扰词。我尝试了null作为停止列表,0和1作为重音,但都没有帮助

如果您运行以下两个查询,很明显,巴西的停止列表是非常不同的。它没有数字。也许应该。也许需要一个支持电话

SELECT s.stopword, l.name
FROM sys.fulltext_system_stopwords s
JOIN sys.fulltext_languages l
ON l.lcid = s.language_id
WHERE l.lcid = 1033

stopword
----------------------------------------------------------------
$
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
...

SELECT s.stopword, l.name
FROM sys.fulltext_system_stopwords s
JOIN sys.fulltext_languages l
ON l.lcid = s.language_id
WHERE l.lcid = 1046

stopword
----------------------------------------------------------------
a
abaixo
acaso
aceleradamente
acerca
acima
acolá
ademais
adentro
adiantado
adiante
adrede
afora
agora
agorinha
ainda
alerta
algo
algum
alguma
algumas
...

LIKE和CONTAINSTABLE可能会有不同的结果。LIKE使用简单且确定的模式匹配规则,并且所有字符都是重要的。CONTAINSTABLE使用一个复杂的系统,试图应用特定于语言的算法进行模糊匹配

如果存储可以是不同语言的文档,则在CONTAINSTABLE中指定语言可以产生更好的结果。LCID可能存储在文档的记录中,并在联接中传递给CONTAINSTABLE。如果未指定,则使用全文的语言,可能不匹配

SELECT ID, Title, KEY_TBL.RANK  
FROM Programs AS DocTable   
INNER JOIN CONTAINSTABLE(Programs, Title, 'Horas', 1046) AS KEY_TBL  
  ON DocTable.ID = KEY_TBL.[KEY]  
WHERE KEY_TBL.RANK > 0  
ORDER BY KEY_TBL.RANK DESC;
更新: 这里有一种方法可以检查在哪种语言中,值是stopword

select * from sys.fulltext_system_stopwords
WHERE stopword IN ('5', 'em')

stopword                                                         language_id
---------------------------------------------------------------- -----------
5                                                                0
5                                                                1028
5                                                                1030
5                                                                1031
5                                                                1033
5                                                                1036
5                                                                1040
5                                                                1041
5                                                                1043
5                                                                1045
5                                                                1049
5                                                                1053
5                                                                1054
5                                                                1055
5                                                                2052
5                                                                2057
5                                                                2070
5                                                                3082
em                                                               1046
em                                                               2070

您正在使用哪个dbms?(该功能是特定于产品的。)哪些列有全文索引?我正在使用sql server。这些列是Id和标题。我创建了表并创建了全文索引。我得到了4条记录。也许你可以重新创建全文索引,看看它是否会更改结果。感谢你的帮助。我不知道这些评估查询,它们非常有用。有了这些信息我尝试对葡萄牙语使用相同的选择。
select s.stopword,l.name FROM sys.fulltext\u system\u stopword s JOIN sys.fulltext\u languages l ON l.lcid=s.language\u id,其中l.lcid=2070
葡萄牙语中存在数字stopwords 0,1,2,3,4…但在执行查询时
选择出现,特殊术语,左侧(显示术语,20)如下[display_term]来自sys.dm_fts_解析器('5 Horas em Islamabad',2070,0,0)
我得到了与使用巴西语言相同的结果
1精确匹配tt24050000 1精确匹配5小时1精确匹配tt24170000 2噪音词em 3精确匹配伊斯兰堡
我认为问题仍然存在于我在全文索引中定义的语言中。我定义了我的语言e“巴西”,如果在我的选择中定义了语言1046,则不会返回值。如果在列的完整索引中定义了语言英语,则会返回所有值。我担心的是将我的列的语言更改为另一种语言(英语)当搜索其他单词时,也会出现错误的结果。
SELECT ID, Title, KEY_TBL.RANK  
FROM Programs AS DocTable   
INNER JOIN CONTAINSTABLE(Programs, Title, 'Horas', 1046) AS KEY_TBL  
  ON DocTable.ID = KEY_TBL.[KEY]  
WHERE KEY_TBL.RANK > 0  
ORDER BY KEY_TBL.RANK DESC;
select * from sys.fulltext_system_stopwords
WHERE stopword IN ('5', 'em')

stopword                                                         language_id
---------------------------------------------------------------- -----------
5                                                                0
5                                                                1028
5                                                                1030
5                                                                1031
5                                                                1033
5                                                                1036
5                                                                1040
5                                                                1041
5                                                                1043
5                                                                1045
5                                                                1049
5                                                                1053
5                                                                1054
5                                                                1055
5                                                                2052
5                                                                2057
5                                                                2070
5                                                                3082
em                                                               1046
em                                                               2070