2013-03-04 61 views
1

我已经根据系统列表创建了一个停止列表,并且设置了我的全文索引来使用它。SQL Server 2008 - 全文搜索不会停在停用词

如果我运行代码select unique_index_id, stoplist_id from sys.fulltext_indexes我可以看到我的所有索引都使用了ID 5的阻止列表,这是我创建的列表。

当我使用FTS_PARTIAL运行文本时,结果是正确的。 例如:

SELECT special_term, display_term 
FROM sys.dm_fts_parser 
(' "Rua José do Patrocinio nº125, Vila América, Santo André - SP" ', 1046, 5, 0) 

我加入到停止列表中的词是示出作为噪声字。但由于某种原因,当我运行我的查询时,它也给我带了停用词的寄存器。

例如:

SELECT * 
FROM tbEndereco 
WHERE CONTAINS (*, '"rua*" or "jose*"') 

引出了上面我所期望的寄存器。既然'鲁阿'这个词应该被忽略,但'何塞'会是一场比赛。

但是如果我搜索:

SELECT * 
FROM tbEndereco 
WHERE CONTAINS (*, '"rua*"') 

我希望没有寄存器被发现。因为'rua'被设置为一个停用词。

我使用巴西(葡萄牙语)作为停用列表语言。 因此,“Rua”(即“街道”)这个词应该被忽略(因为我将它添加到了停止列表中)。它被解析器识别为噪声,但是当我运行我的查询时,它给我带有“Rua”的寄存器。

我的搜索是一个地址搜索,所以它应该忽略诸如“街道”,“大道”等词(当然是葡萄牙语,我也将它们都添加了)。

这是我用来查询表的查询。

select DISTINCT(PES.idPessoa) 
, PES.Nome     
, EN.idEndereco 
, EN.idUF  
, CID.Nome as Cidade 
, EN.Bairro  
, EN.Logradouro 
, EN.Numero 
, EN.Complemento 
, EN.CEP 
, EN.Lat 
, EN.Lng  
from tbPessoa PES 
INNER JOIN tbAdvogado ADV ON PES.idPessoa = ADV.idPessoa 
INNER JOIN tbEndereco EN ON PES.idEmpresa = EN.idEmpresa 
LEFT JOIN tbCidade CID ON CID.idCidade = EN.idCidade 
where adv.Ativo = 1 
and CONTAINS (en.*, '"rua*"') 
OR EN.idCidade IN (SELECT idCidade 
       FROM tbCidade 
       WHERE CONTAINS (*, '"rua*"')) 
OR PES.idPessoa IN (SELECT DISTINCT (ADVC.idPessoa) 
       FROM tbComarca C 
       INNER JOIN tbAdvogadoComarca ADVC 
            ON ADVC.idComarca = C.idComarca 
       WHERE CONTAINS (Nome, '"rua*"')) 
OR PES.idPessoa IN (SELECT OAB.idPessoa 
       FROM tbAdvogadoOAB OAB 
       WHERE CONTAINS (NROAB, '"rua*"')) 

我试过FREETEXT和CONTAINS。使用一些简单的像WHERE CONTAINS (NROAB, 'rua'))但它也给我带有“Rua”的寄存器。

我以为我的查​​询可能有一些问题,然后我尝试了一个更简单的查询,它也给我带来了停止词“Rua”。

SELECT * 
FROM tbEndereco 
WHERE CONTAINS (*, 'rua') 

我注意到的一件事是,从系统stoplist本地工作的单词工作得很好。例如,如果我尝试使用“do”(意思是“of”)这个词,它不会给我任何寄存器。

例子:

SELECT * 
FROM tbEndereco 
WHERE CONTAINS (*, '"do*"') 

我试图运行命令“启动完全填充”通过SSMS中的所有表来检查是否是问题,什么也没得到。

我在这里错过了什么。这是我第一次使用Fulltext索引,并且可能会错过设置它的一些要点。

非常感谢您的支持。

Regards,

Cesar。

+0

谢谢@Rafael Colucci的回答。我在阅读您的答案后编辑了我的问题,因为我可以明白为什么您认为我希望将停用词从结果寄存器中删除。因为我真的写过。 =)谢谢。 – 2013-03-05 12:29:40

回答

1

你改变了你的问题,所以我会改变我的答案,并尝试解释它好一点。

根据Stopwords and Stoplists

停用词可以在特定的语言与意义的词,或者 可以是不具有语言意义的象征。例如,在 英文中,诸如“a”,“and”,“is”和“the”的词是 被全文索引省略,因为它们被认为对 搜索没有用处。

虽然它忽略了包含停用词,但全文索引 确实考虑了它们的位置。例如,考虑 短语“说明适用于这些Adventure Works Cycles 模型”。下表描述的字的位置在 短语:

我不知道为什么,但我想使用像一个短语搜索时,它仅适用于:

如果你有这样一行:

Teste anything casa 

你查询全文如下:

SELECT * 
FROM Address 
WHERE CONTAINS (*, '"teste rua casa"') 

行:

Teste anything casa 

将被退回。当您查询使用“或”运算符或仅搜索一个词的规则不适用的全文

"Search for 'teste' near any word near 'casa'" 

:在这种情况下,全文将您的查询翻译为这样的事情。我已经测试了几次,历时约3个月,我从未理解为什么。

编辑

,如果你有行

"Rua José do Patrocinio nº125" 

和您查询全文

"WHERE CONTAINS (, '"RUA" or "Jose*" or "do*"')" 

,因为它包含的词中的至少一个会带来行你正在寻找,而不是因为“rua”和“do”这个词被忽略。

+0

嗯,我认为停用词会忽略搜索中的单词。 例如 我期望停用词以这种方式工作。 如果我使用子句: “Where CONTAINS(*,'”RUA *“或”Jose *“或”do *“')”搜索“RuaJosédo Patrocinionº125”,这是我将查询装入C#,它会给我上面的注册表,因为2个单词“rua”和“do”可能会被忽略,但是搜索会匹配“Jose”。 但是,如果我搜索“在哪里包含(*,'”RUA *“或”do *“')”。它不会给我带来什么,因为我正在搜索的词语被忽略了。 我只是没有得到它是如何工作的? – 2013-03-05 12:11:04

+0

这是我认为应该做的。但它没有发生。我们花费了大量的时间,我们决定创建一个算法,在创建搜索查询时忽略停用词。 – 2013-03-05 13:01:20

+0

令我感兴趣的是它的行为方式应该是系统给出的停用词。只有我添加的那些不能正常工作。 :S – 2013-03-05 13:20:18