【问题标题】:SQL Server 2008 - fulltext search not stopping on stop wordsSQL Server 2008 - 全文搜索不在停用词上停止
【发布时间】:2013-02-19 02:40:45
【问题描述】:

我根据系统列表创建了一个停止列表,并设置了全文索引以使用它。

如果我运行代码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*"')

如我所料,把上面的寄存器给我。因为“rua”这个词应该被忽略,但“Jose”会匹配。

但如果我搜索:

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

我希望找不到任何寄存器。由于 'rua' 被设置为停用词。

我使用巴西(葡萄牙语)作为停止列表语言。 所以“Rua”这个词(意思是“Street”)应该被忽略(因为我将它添加到停止列表中)。解析器将其识别为噪声,但是当我运行查询时,它会给我带来包含“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')

我注意到的一件事是,系统停止列表中的本地单词可以正常工作。例如,如果我尝试使用“do”(意思是“of”)这个词,它不会给我带来任何寄存器。

例子:

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

我尝试在所有表中通过 SSMS 运行命令“开始完全填充”,以检查是否是问题所在,但没有得到任何结果。

我在这里错过了什么。这是我第一次使用全文索引,我可能会遗漏一些设置。

提前感谢您的支持。

问候,

塞萨尔。

【问题讨论】:

  • 感谢@Rafael Colucci 的回答。在阅读您的答案后,我编辑了我的问题,因为我明白您为什么认为我希望从结果寄存器中删除停用词。因为我真的写过。 =) 谢谢。

标签: sql-server-2008 full-text-search stop-words


【解决方案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”被忽略了。

【讨论】:

  • 好吧,我认为停用词会忽略搜索中的单词。例如,我希望停用词以这种方式工作。如果我使用以下子句搜索“Rua José do Patrocinio nº125”:“WHERE CONTAINS (, '"RUA" or "Jose*" or "do*"')" 这是我安装的方式我在 C# 中的查询,它会给我带来上面的寄存器,因为“rua”和“do”这两个词可能会被忽略,但搜索会匹配“Jose”。但如果我搜索“WHERE CONTAINS (, '"RUA" or "do*"')”。它不会给我带来任何东西,因为我正在搜索的单词被忽略了。我只是不明白它是如何工作的吗?
  • 这是我认为应该做的。但它不会发生。我们为此花费了大量时间,并决定创建一种算法,在创建搜索查询时忽略停用词。
  • 让我感兴趣的是,对于系统给出的停用词,它的行为方式应有尽有。只有我添加的那些不能正常工作。 :S
  • 好像是这样。我会忽略有人在我的搜索中只写“rua”的可能性,它会给我带来所有包含它的寄存器“几乎每条街道”:D。我在谷歌地图中测试过它,它也是如此。所以我是谁说它不应该发生。 ;) 感谢您的帮助@Rafael,您几个月的学习为我节省了宝贵的时间。问候。塞萨尔。
  • 你错了。如果您有“Rua José do Patrocinio nº125”这一行并且您查询“WHERE CONTAINS (, '"RUA" or "Jose*" or "do*"')" 它会带来该行,因为它确实包含至少一个您正在搜索的单词。此外,“do*”表示“任何以“do”开头的内容。如果您使用“do*”查询 sys.dm_fts_parser,它将显示完全匹配。而不是干扰词。
猜你喜欢
  • 1970-01-01
  • 2012-01-16
  • 2012-07-21
  • 2014-01-06
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 2011-06-10
相关资源
最近更新 更多