2009-10-16 81 views
1

有人可以建議的想法,如何將用戶輸入(少量字)匹配到系統中適當的標籤(每個標籤也是1或N個字)?用戶搜索關鍵字與標籤的匹配

這裏是示例來演示問題: 我有一個標籤,分配給對象。例如(標籤昏迷分開的,但在現實生活中,我有關係表)

Object     Tags 
Earth     World, reality 
World of warcraft 3  World Of warcraft, virtual reality 
quake     game, virtual 

我想獲得如下:

用戶輸入「世界‘:結果是’地球 '

用戶輸入' 魔獸世界的 ':結果是' 魔獸世界3'的

這很簡單,精確搜索。但是:

用戶輸入 '遊戲世界 ':結果應該是由兩個標籤 - ' 地球', '地震'

用戶輸入 '虛擬現實':返回所有3個記錄

用戶輸入 '現實虛擬':地球,地震

我正在使用t-sql進行搜索,全文搜索已啓用並用於在主文本中查找關鍵字。 C#是中間層。但我更喜歡在t-sql級別上有解決方案。

更新1 首先我所要做的,是不允許空格標籤,像計算器。任何其他想法都會被提升。

回答

0

將這種複雜的業務邏輯放入SQL代碼中並不是一個好主意!把它放在中間層,如果你擔心性能使用一些緩存機制。

+0

好點。不過,我擔心在C#級別將所有關鍵字組合與標籤匹配的速度會變慢。 – st78 2009-10-16 08:47:15

+0

情況正好相反。除非您擁有大量關鍵字(> 100MB),否則不需要全文索引。你總是可以用嵌套的hashtables/dictionnaries來實現c#索引。 – Manu 2009-10-16 08:59:25

+0

雖然,除非你的數據庫(這是唯一的),你實際上可以有多個使用C#代碼的服務器......這裏有自然的平行性! – 2009-10-16 09:02:43

1

你需要的分裂功能在搜索字符串分割標記,然後嘗試在標籤

FUNCTION [dbo].[SplitString] 
(
     @String VARCHAR(8000) , 
     @Delimiter VARCHAR(10) 
) 
RETURNS @RetTable TABLE(
     String varchar(1000) 
) 
AS 
BEGIN 
    DECLARE @i INT , 
      @j INT 
    SELECT @i = 1 
    WHILE @i <= LEN(@String) 
    BEGIN 
     SELECT @j = CHARINDEX(@Delimiter, @String, @i + 1) 
     IF @j = 0 
     BEGIN 
      SELECT @j = LEN(@String) + 1 
     END 
     INSERT @RetTable SELECT LTRIM(RTRIM(SUBSTRING(@String, @i, @j - @i))) 
     SELECT @i = @j + LEN(@Delimiter) 
    END 
    RETURN 
END 


DECLARE @String VARCHAR(8000) , 
     @Delimiter VARCHAR(10) 
DECLARE @RetTable TABLE(
     String varchar(1000) 
) 

SELECT @String = 'world of ', 
     @Delimiter = ' ' 

--split FUNCTION that returns a table of tags to match 
    DECLARE @i INT , 
      @j INT 
    SELECT @i = 1 
    WHILE @i <= LEN(@String) 
    BEGIN 
     PRINT @i 
     SELECT @j = CHARINDEX(@Delimiter, @String, @i + 1) 
     IF @j = 0 
     BEGIN 
      SELECT @j = LEN(@String) + 1 
     END 
     INSERT @RetTable SELECT LTRIM(RTRIM(SUBSTRING(@String, @i, @j - @i))) 

     SELECT @i = @j + LEN(@Delimiter) 
    END 

SELECT * FROM @RetTable 
--split FUNCTION that returns a table of tags to match 

DECLARE @Table TABLE(
     Objects VARCHAR(MAX), 
     Tags VARCHAR(MAX) 
) 

INSERT INTO @Table (Objects,Tags) SELECT 'Earth', 'World,reality' 
INSERT INTO @Table (Objects,Tags) SELECT 'World of warcraft 3', 'World Of warcraft,virtual,reality' 
INSERT INTO @Table (Objects,Tags) SELECT 'quake', 'game,virtual' 


SELECT DISTINCT 
     t.* 
FROM @Table t, 
     @RetTable r 
WHERE Tags LIKE '%' + String + '%,%' 
OR  Tags LIKE '%,%' + String + '%,%' 
OR  Tags LIKE '%,%' + String + '%' 

類似的東西進行匹配。

3

您可能需要使用Velocity緩存引擎進行調查,因爲它有用於標記(GetObjectsByTagGetObjectsByAllTagsGetObjectsByAnyTag)和所有的辛勤工作已經爲你做了相當豐富的支持!你所要做的就是用適當的標籤將你的對象加載到緩存中。

+0

感謝您的鏈接,我不知道它。我一定會檢查它。 但是,這僅僅是我的搜索問題的一部分,我很少有機會使用第三方。 – st78 2009-10-16 09:57:25

+1

取決於你如何解釋第三方。如果你已經在使用C#,那麼它只是微軟的另一個組件。 – PhilPursglove 2009-10-16 10:21:38