我正在我的网站上创建一个小搜索功能,这样就可以搜索系统中的文章。每篇文章都有一组与之关联的关键字,这些关键字存储在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
有什么想法吗?
答案 0 :(得分:3)
SQL Server可以使用全文搜索。您可以使用CONTAINs和CONTAINSTABLE或FREE TEXT和FREETEXTTable来代替自己创建搜索功能
答案 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子句应该起作用......