SQL CONTAINSTABLE-意外结果
我有一个带有一些记录的表格程序,如果使用LIKE或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',
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