我知道我可以运行类似下面的搜索来查找包含同一单词的多种形式的行(例如“锤子”):
SET @currentWord = 'hammers'
SET @stemSearch = 'FORMSOF(INFLECTIONAL,' + @currentWord + ')'
SELECT @matches = count(word) FROM tblWord WHERE CONTAINS(word, @stemSearch)
是否有可能编写一个存储过程(或以其他方式得到该词的根,最好具有与MSSQL相同的结果),给定任何形式的单词将只返回该单词的根? (例如“锤子”用于“锤子”,或“鹅”用于“鹅”)
答案 0 :(得分:1)
我认为答案是肯定的。你需要有一个单词库,它们的根等等。例如,你需要提供以下信息:'monk'和'monkey'是否具有相同的根?我建议阅读SOUNDEX
也许这会为你做的
SET @currentWord = 'hammers'
SET @stemSearch = 'FORMSOF(INFLECTIONAL,' + @currentWord + ')'
SELECT @matches = count(word) FROM tblWord WHERE SOUNDEX(word)=SOUNDEX(@stemSearch)
或
SET @currentWord = 'hammers'
SET @stemSearch = 'FORMSOF(INFLECTIONAL,' + @currentWord + ')'
SELECT @matches = count(word) FROM tblWord WHERE DIFFERENCE(word, @stemSearch) IN (4,3)
答案 1 :(得分:1)
我仍在研究细节,但现在这是一个部分解决方案:
我创建了一个表和一个将用于此目的的存储过程。该表有一个代理键,一个名为word
的列和一个名为associatedWordId
的列。
存储过程使用fn_Split将输入列表(例如'dog,dogs,cat,cats'
)拆分为表变量,然后将它们插入到永久表中(需要在{{1}上获取全文索引) }专栏)。
然后使用word
搜索循环遍历表格内容,并标记所有相关字词(包括将搜索字词与自身匹配)。
然后,我可以查询结果表格,将我的报告数据分组为同一个单词的多种形式。
存储过程存在一个问题(稍后会详细介绍);但到目前为止这是我的过程:
FORMSOF(INFLECTIONAL, ...)
虽然这并没有解决我最初获得输入词干的目标,但它确实解决了我在报告中对同一个词的多种形式进行分组的迫切需要。
这就是问题:
第一次运行proc时,它会返回associatedWordId列的所有CREATE PROCEDURE [dbo].[usp_identifyWordAssociations] (
@words varchar(max)
)
AS
--clear out the existing data
delete from tblWordAssociation
--insert the new words
insert into tblWordAssociation (word)
select [value] from fn_splitList(@words)
--get a copy to loop from
create table #myTmpTable (
word varchar(100)
)
insert into #myTmpTable
select word from tblWordAssociation
--loop over each word
declare @word varchar(100), @wordId int, @wordParent int, @stemSearch varchar(120)
while exists (select top 1 word from #myTmpTable)
begin
select top 1 @word = word from #myTmpTable
--get the word information
select top 1 @wordId = id, @wordParent = associatedWordId
from tblWordAssociation where word = @word
--if the word hasn't already been looked up
if (@wordParent is null)
begin
--setup stem search
set @stemSearch = 'FORMSOF(INFLECTIONAL,' + @word + ')'
--update all other forms of the current word with this word
update tblWordAssociation
set associatedWordId = @wordId
where
id in (
--get words that are other forms of the current word
select id
from tblWordAssociation
where
contains (word, @stemSearch)
and
associatedWordId is null
)
end
--now that we're done with this word, remove it from the temp table
delete from #myTmpTable
where word = @word
end
drop table #myTmpTable
select id, word, associatedWordId from tblWordAssociation
GO
值。如果我然后立即重新运行它,我得到所需的输出。我猜这与索引创建的时间有关。我在填充永久表(null
)之后但在开始循环之前尝试添加select *
,但是没有解决它。
我尝试将存储过程拆分为两个:一个用于删除/插入,另一个用于更新+选择。当快速连续运行时,这并没有解决问题;但是,如果我在运行它们之间暂停一下,结果就像预期的那样。我相信这表明索引需要一定的时间来构建。因此,我能想到的唯一合乎逻辑的事情是让我的应用程序扫描第二个proc的结果为NULL,如果找到,请等待几秒钟再试一次。
有没有办法让我的proc等到构建索引之后再继续?
答案 2 :(得分:0)
是的,您可以获得SQL Server在CONTAINS查询中使用的相同屈折表单。可以使用以下函数直接调用SQL Server FTS解析器,此函数可以使用CONTAINS中使用的任何谓词:
SELECT * FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL, "dogs")', 1033, NULL, 1)