I have a table with the following contents:
- CategoryID
- ParentID
- Name
I would like to have a search functionality that would search the whole hierarchy, for exmple this is the breadcrumb of a category:
Motorcycles/Japan/Kawasaki/600cc to 800cc/1998-2004
If someone searches for "600cc Kawasaki" I would like the above category to be returned. So the categorypath which has the most matches should return.
At the moment I came up with this:
IF ISNULL(@searchTerm, '') = ''
    SET @searchTerm = '""'
DECLARE @Result TABLE (CategoryId int) 
DECLARE CategoryCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT CategoryId, ParentId, Name
FROM Category
WHERE FREETEXT([Name], @searchTerm)
OPEN CategoryCursor
DECLARE @CategoryId int
DECLARE @ParentId int
DECLARE @Name nvarchar(100)
FETCH NEXT FROM CategoryCursor INTO @CategoryId, @ParentId, @Name
WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @FullPath nvarchar(1000)
    SET @FullPath = @Name
    WHILE @ParentId <> 0
    BEGIN
        SELECT @ParentId = ParentId, @Name = [Name]
        FROM Category 
        WHERE CategoryId = @ParentId
        SET @FullPath = @Name + '\' + @FullPath     
    END
    -- Check if @FullPath contains all of the searchterms
    DECLARE @found bit
    DECLARE @searchWords NVARCHAR(100)
    DECLARE @searchText NVARCHAR(255)
    DECLARE @pos int
    SET @found = 1
    SET @searchWords = @searchTerm + ' '
    SET @pos = CHARINDEX(' ', @searchWords)
    WHILE @pos <> 0
        BEGIN
        SET @searchText = LEFT(@searchWords, @pos - 1)
        SET @searchWords = STUFF(@searchWords, 1, @pos, '')
        SET @pos = CHARINDEX(' ', @searchWords)
        IF @searchText = '' CONTINUE
        IF @FullPath NOT LIKE '%' + @searchText + '%' 
            BEGIN
                SET @found = 0
            BREAK
            END
        END
    IF @found = 1
        INSERT INTO @Result VALUES(@CategoryId)
    FETCH NEXT FROM CategoryCursor INTO @CategoryId, @ParentId, @Name
END
CLOSE CategoryCursor
DEALLOCATE CategoryCursor
SELECT * 
FROM Category 
WHERE categoryID IN (SELECT categoryId FROM @Result)
This will first find all catagorynames which contain any of the searchwords. Problem is, I don't want "600cc" for other brands to return, only the one which is related to "Kawasaki". So next I build the breadcrumb for the current category and see if it contains all of the searchwords.
It works but I think it is ineffective so i'm looking for a better method.
Perhaps storing the complete path as text in a new column and search on that?
 
    