搜索功能,SQL Server

时间:2009-11-22 15:24:21

标签: sql sql-server search join

我正在我的网站上创建一个小搜索功能,这样就可以搜索系统中的文章。每篇文章都有一组与之关联的关键字,这些关键字存储在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]

每篇文章都可以包含无限量的关键字。现在我的问题是搜索本身。 例如,用户键入:

法国演员

我希望系统能够使用关键字France和actors找到所有文章(只有DISTINCT)。我将搜索条件作为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

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

SQL Server可以使用全文搜索。您可以使用CONTAINs和CONTAINSTABLE或FREE TEXT和FREETEXTTable来代替自己创建搜索功能

Way of searching 30,000 SQL Records

答案 1 :(得分: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,则不需要加入文章,所以我删除了该表。

答案 2 :(得分: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,则内连接方法可能也可以正常工作。

答案 3 :(得分: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子句应该起作用......