2009-11-22 67 views
0

我在我的網站上創建了一個小型搜索功能,這使得可以搜索系統中的文章。每篇文章都有一組與其關聯的關鍵字,這些關鍵字存儲在SQL Server數據庫中。搜索功能,SQL Server

這是表:

CREATE TABLE [dbo].[SearchWords] (
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [ArticleID] [int] NOT NULL, 
    [SearchWord] [nvarchar](20) NOT NULL, 
    CONSTRAINT [PK_SearchWords] PRIMARY KEY CLUSTERED 
     ([ID] ASC) 
     WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
       IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
       ALLOW_PAGE_LOCKS = ON) 
     ON [PRIMARY] 
) ON [PRIMARY] 

每篇文章都可以使用關鍵字無限量的。現在我的問題是搜索本身。 舉例而言,當用戶鍵入:

法國演員

我希望系統找到關鍵字法國和演員所有文章(只有一次不同)。我將搜索條件作爲varchar(以空格分隔)傳遞給存儲過程。然後,我用下面的函數分詞:(Erland Sommarskog)http://www.sommarskog.se/arrays-in-sql-2005.html#iter-list-of-strings

然後我如何匹配搜索詞的標準詞並只獲得不同的文章ID?

我正在處理類似這樣的事情,只是我無法理解如何匹配所有關鍵字。如果只輸入一個關鍵字,則此方法有效。如果用戶輸入多個,那麼即使該文章包含所有涉及的關鍵字,它也不會返回任何內容。

declare @temp nvarchar(50) 
set @temp = 'France actors' 

SELECT DISTINCT Article.ArticleID 
FROM Article 
INNER JOIN SearchWords 
    ON Article.ArticleID = SearchWords.ArticleID 
JOIN iter_charlist_to_tbl(@temp, DEFAULT) s 
    ON SearchWords.SearchWord = s.nstr 

任何想法?

回答

2

首先,您鏈接的UDF的默認分隔符是,字符,而不是空格。因此,使用默認分隔符時,您會得到單個行,並且包含兩個單詞。 (調試提示:當某些東西不能正常工作時,把它拆開,在這種情況下,你應該完成了一個select * from UDF(@temp, DEFAULT)來查看錶格是否正確。)

假設你想繼續使用那個UDF並且你想要匹配任何搜索條件(但不一定是全部)的那個文章,這些方針的東西應該是正確的:

declare @temp nvarchar(50) 
set @temp = 'France actors' 

SELECT DISTINCT 
    a.ArticleID 
FROM 
    Article a 
    JOIN SearchWords sw ON a.ArticleID = sw.ArticleID 
WHERE 
    exists (
    select 
     1 
    from 
     iter_charlist_to_tbl(@temp, ' ') s 
    where 
     s.nstr = sw.SearchWord 
) 

你的內連接方法,如果您更改參數的UDF也許應該正常工作。

+0

這將如何確保你同時匹配'France'和'actors'? – Andomar

+0

啊,對。我的錯誤太快瀏覽了這個問題。開始重寫它,但我得到了與上述相同的解決方案,並且沒有理由發佈那兩次。 – Donnie

+0

我稍微更改了您的代碼,以返回匹配關鍵字的數量。這樣我可以顯示結果,首先產生最高的關鍵字匹配。 有沒有辦法來捕獲這個產量的記錄數量?我將它與一個返回記錄的C#SQL-to-Linq類相結合。但是,我希望它也可以返回一個OUTPUT int與匹配的記錄數。我需要向用戶顯示找到的總行數,並且還可以使用.Skip(x)行數。 – Patrick

0

嘗試這樣的事情...

SET @Temp = ','+replace(@temp,' ',',')+',' 

SELECT DISTINCT article.ArticleID 
FROM article 
JOIN SearchWords ON Article.ArticleID=SearchWords.ArticleID 
WHERE CharIndex(','+SearchWords.SearchWord+',',@temp) > 0 

我不知道你是如何分離你的文本輸入到獨立的話,那麼你可能需要的分隔符從一個逗號改變,或做多一點代碼來建立逗號分隔的字符串,但一旦建立,上面的加入和where子句應該做的伎倆...

2

你可以使用group by來做到這一點,然後要求找到的關鍵字數等於總數關鍵字:

SELECT SearchWords.ArticleID 
FROM SearchWords 
INNER JOIN iter_charlist_to_tbl(@temp, DEFAULT) s 
    ON SearchWords.SearchWord = s.nstr 
GROUP BY SearchWords.ArticleID 
HAVING COUNT(*) = (
    select count(*) from iter_charlist_to_tbl(@temp, DEFAULT) 
) 

順便說一句,如果你只是在尋找ArticleID,你不需要加入文章,所以我刪除了該表。

3

SQL Server具有全文搜索功能,您可以使用。而不是自己裝箱的搜索功能,您可以使用包含和CONTAINSTABLE或FREETEXT和FREETEXTTABLE

Way of searching 30,000 SQL Records

+0

全文也很好,因爲你還可以用它匹配的是相關的詞或聽起來像你的話,那麼「驅動器」也可以匹配「驅動器」等 - 如果你想。 – eidylon

+0

問題是我不允許創建全文表格... – Patrick

+0

不允許?恥辱,因爲我認爲創建比使用FTS更快的自定義解決方案很困難。 –