我有一個表格,其中有一個列爲nvarchar(max)
,其中的文字從文檔中提取。我怎樣才能創建一個選擇查詢,我會傳遞另一個關鍵字列表作爲參數,並返回按匹配數量排序的行?用於匹配關鍵字的SQL查詢?
也許這是可能與全文搜索?
我有一個表格,其中有一個列爲nvarchar(max)
,其中的文字從文檔中提取。我怎樣才能創建一個選擇查詢,我會傳遞另一個關鍵字列表作爲參數,並返回按匹配數量排序的行?用於匹配關鍵字的SQL查詢?
也許這是可能與全文搜索?
是的,可能與全文檢索,並有可能最好的答案。對於直接的T-SQL解決方案,您可以使用拆分功能並加入,例如假設所謂的dbo.Numbers號碼錶(你可能需要決定在不同的上限):
SET NOCOUNT ON;
DECLARE @UpperLimit INT;
SET @UpperLimit = 200000;
WITH n AS
(
SELECT
rn = ROW_NUMBER() OVER
(ORDER BY s1.[object_id])
FROM sys.objects AS s1
CROSS JOIN sys.objects AS s2
CROSS JOIN sys.objects AS s3
)
SELECT [Number] = rn - 1
INTO dbo.Numbers
FROM n
WHERE rn <= @UpperLimit + 1;
CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers([Number]);
和使用數字該表中的劃分功能:
CREATE FUNCTION dbo.SplitStrings
(
@List NVARCHAR(MAX)
)
RETURNS TABLE
AS
RETURN
(
SELECT DISTINCT
[Value] = LTRIM(RTRIM(
SUBSTRING(@List, [Number],
CHARINDEX(N',', @List + N',', [Number]) - [Number])))
FROM
dbo.Numbers
WHERE
Number <= LEN(@List)
AND SUBSTRING(N',' + @List, [Number], 1) = N','
);
GO
然後你就可以簡單地說:
SELECT key, NvarcharColumn /*, other cols */
FROM dbo.table AS outerT
WHERE EXISTS
(
SELECT 1
FROM dbo.table AS t
INNER JOIN dbo.SplitStrings(N'list,of,words') AS s
ON t.NvarcharColumn LIKE '%' + s.Item + '%'
WHERE t.key = outerT.key
);
作爲順序:
CREATE PROCEDURE dbo.Search
@List NVARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT key, NvarcharColumn /*, other cols */
FROM dbo.table AS outerT
WHERE EXISTS
(
SELECT 1
FROM dbo.table AS t
INNER JOIN dbo.SplitStrings(@List) AS s
ON t.NvarcharColumn LIKE '%' + s.Item + '%'
WHERE t.key = outerT.key
);
END
GO
然後你可以通過@List
(例如來自C#的文件編號爲EXEC dbo.Search @List = N'foo,bar,splunge'
)。
這會不會是超級快,但我敢肯定,這將是比所有的數據拉出到C#和雙嵌套循環它手動更快。
謝謝!但那是什麼UpperLimit? – Gustav
您希望傳遞給@List的最長字符串的長度。或者您希望用於其他目的的最大數量(Numbers表對於許多功能非常方便 - 請參閱http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-numbers- table.html)。如果不清楚,請不要在每次運行查詢時創建Numbers表 - Numbers表和函數只應創建一次。 –
how to ... return the rows ordered by the number of [full-text] matches
我沒有用它自己,而是相信SQL Server 2008支持加權的CONTAINSTABLE相匹配,這可能是對你有所幫助:
http://msdn.microsoft.com/en-us/library/ms189760.aspx
如果沒有發動機是返回結果的點擊次數加權...
你可以寫一個UDF,它有兩個輸入,並返回一個整數:大textvalue是第一個輸入和字Y你在尋找一個逗號分隔的字符串是第二個。該函數返回一個整數,表示不同的查找單詞,這些單詞在文本中至少發現一次,或查找單詞的總次數。實施 - 如何減肥 - 取決於你。例如,你可能希望按照最重要或最不重要的順序來排列所查找的單詞,並且讓一個重要的單詞比一個不太重要的單詞更重要。
然後,您可以使用您的全文搜索引擎來查找包含的話至少一個(你會或它們)的所有記錄,而你運行這個結果,通過你的UDF標量函數設置:
pseudo code
select title, weightfunction(summary, 'word1,word2,word3....wordN')
from docs
where summary contains (word1 or word2 or word3 ... or wordN)
order by weightfunction(summary, 'word1,word2,word3....wordN') desc
你試過什麼了嗎? – msarchet
是的...我選擇所有的行,並在C#中手動執行...生產系統非常慢 – Gustav
@Gustav你能展示你在C#中嘗試過什麼嗎? – reggie