Search code examples
sql-serverfull-text-searchformsof

Can FORMSOF be nested?


I'm trying to see if the Full-Text Search feature of SQL Server can be used in a certain way.

My idea is to do something like: Take N keywords and search for all the forms of said keywords and its synonyms.

What I came up with was something along these lines:

SELECT * 
FROM table
WHERE CONTAINS(*, CONTAINS(*,'FORMSOF(THESAURUS,FORMSOF(INFLECTIONAL,"keyword"))')

But this query doesn't work. Is this even possible? Is my idea reasonable, or am I going mad?


Solution

  • I think you'll have to do something like this:

    Select * from TABLE
    Where 
      CONTAINS(*,'FORMSOF(THESAURUS,"keyword")')
      OR
      CONTAINS(*,'FORMSOF(INFLECTIONAL,"keyword")')
    

    EDIT

    Otherwise, you might have to dynamically build the CONTAINS search conditions like this:

    IF OBJECT_ID('tempdb..#A') IS NOT NULL DROP TABLE #A
    IF OBJECT_ID('tempdb..#B') IS NOT NULL DROP TABLE #B
    
    CREATE TABLE #A (pk INT IDENTITY(1,1), word nvarchar(50))
    CREATE TABLE #B (word nvarchar(50))
    
    -- load words from thesaurus
    INSERT INTO #A (word)
      SELECT display_term 
      FROM sys.dm_fts_parser('FORMSOF (THESAURUS, "mykeyword")',1033,null,0)
    
    DECLARE @cmd NVARCHAR(1000) , @word NVARCHAR(50);
    DECLARE @k INT;SET @k = ISNULL((SELECT MAX(pk) FROM #A) , 0 )
    
    -- call INFLECTIONAL for each word
    WHILE @k>0
    BEGIN
      SELECT @word = word FROM #A WHERE pk = @k
      SET @cmd = 'INSERT INTO #B (word)
        SELECT display_term 
        FROM sys.dm_fts_parser(''FORMSOF (INFLECTIONAL, "' + @word + '")'',1033,null,0)'
      EXEC(@cmd)
      SET @k = @k - 1
    END
    
    -- list all words
    SELECT * FROM #B
    
    DECLARE @FTString  NVARCHAR(4000);
    SET @FTString  = '';
    
    -- build the list of words for CONTAINS
    SELECT @FTString  = 
        @FTString + 
      + CASE WHEN @FTString='' 
         THEN '' 
         ELSE ' OR ' 
        END
      + '"'+word+'"'
    FROM #B
    
    -- display the CONTAINS condition
    SELECT @FTString
    
    -- final search
    SELECT * 
    FROM dbo.MyTable AS x 
    WHERE CONTAINS(*, @FTString)