2010-01-13 107 views
3

我正在尋找一個很好的解決方案,以有效地使用SQL Server r2005的containstable功能。目前我有,例如員工和地址表。在多個表和列上的SQL Server 2005全文搜索

-Employee 
Id 
Name 

-Address 
Id 
Street 
City 
EmployeeId 

現在用戶只能在一個文本框中輸入搜索條件,我希望使用「AND」運算符來拆分和搜索這些條款。 FREETEXTTABLE似乎自動處理「或」。

現在讓我們說用戶輸入「John Hamburg」。這意味着他想在漢堡找到約翰。 所以這是「John AND Hamburg」。

因此,CONTAINSTABLE會檢查「John AND Hamburg」的每一列,因此以下內容將不包含結果。

所以我的問題是:跨多個列/表執行AND運算符全文搜索的最佳方法是什麼?

SELECT * 
FROM Employee emp 
    INNER JOIN 
     CONTAINSTABLE(Employee, *, '(JOHN AND Hamburg)', 1000) AS keyTblSp 
     ON sp.ServiceProviderId = keyTblSp.[KEY]  
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = emp.EmployeeId 
UNION ALL 
SELECT * 
FROM Employee emp 
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = emp.EmployeeId 
    INNER JOIN 
     CONTAINSTABLE([Address], *, '(JOHN AND Hamburg)', 1000) AS keyTblAddr 
     ON addr.AddressId = keyTblAddr.[KEY]  

... 

回答

2

我有同樣的問題。這是我的解決方案,它適用於我的情況:

我創建了一個視圖,它返回我想要的列。我添加了另一個額外的列,它彙總了我想要搜索的所有列。因此,在這種情況下,視圖將會像

SELECT emp.*, addr.*, ISNULL(emp.Name,'') + ' ' + ISNULL(addr.City, '') AS SearchResult 
FROM Employee emp 
    LEFT OUTER JOIN [Address] addr ON addr.EmployeeId = emp.EmployeeId 

之後,我在SearchResult列上創建了全文索引。然後,我在這一列搜索

SELECT * 
FROM vEmpAddr ea 
INNER JOIN CONTAINSTABLE(vEmpAddr, *, 'John AND Hamburg') a ON ea.ID = a.[Key] 
6

這是更多的語法問題。你如何用一個輸入框來描述用戶的意圖?

  • 他們在找「John Hamburg」這個人嗎?
  • 他們在尋找「約翰漢堡街」嗎?
  • 他們是在尋找住在斯普林菲爾德「漢堡街」的「約翰」嗎?
  • 他們是否在尋找住在「漢堡」城市的「約翰」?

不知道用戶的意圖,最好的你可以期望的是或者這些條款,並採取最高排名點擊。

否則,你需要在一噸的邏輯編程,這取決於傳入的單詞數:

2個字:

足月1搜尋員工數據,搜索的員工數據項2,術語1的搜索地址數據,術語2的搜索地址數據。按術語合併結果,按大部分命中排序。

3個詞語:

爲術語1搜索員工的數據,術語2搜索員工的數據,術語3搜索僱員的數據,術語1搜索地址數據,搜索術語2地址數據,用於搜索地址數據term 3.按照術語合併結果,按大多數命中順序。

等等

我想我會重新設計了GUI的輸入分成的名稱和地址,在最低限度。如果這是不可能的,強制執行的語法規則的效果

EDIT「第01話將被視爲一個名字,直到出現一個逗號,將被視爲地址後的任何話」:

您最好的選擇仍然是或條款,並採取最高排名命中。下面是這方面的一個例子,一個例子,爲什麼這是不理想的,而不輸入一些預處理占卦用戶的意圖:

insert into Employee (id, [name]) values (1, 'John Hamburg') 
insert into Employee (id, [name]) values (2, 'John Smith') 
insert into Employee (id, [name]) values (3, 'Bob Hamburg') 
insert into Employee (id, [name]) values (4, 'Bob Smith') 
insert into Employee (id, [name]) values (5, 'John Doe') 

insert into Address (id, street, city, employeeid) values (1, 'Main St.', 'Springville', 1) 
insert into Address (id, street, city, employeeid) values (2, 'Hamburg St.', 'Springville', 2) 
insert into Address (id, street, city, employeeid) values (3, 'St. John Ave.', 'Springville', 3) 
insert into Address (id, street, city, employeeid) values (4, '5th Ave.', 'Hamburg', 4) 
insert into Address (id, street, city, employeeid) values (5, 'Oak Lane', 'Hamburg', 5) 

現在,因爲我們不知道哪些關鍵字將適用於什麼表,我們必須假設他們可以適用於任何一個表,所以我們必須對每個表進行OR運算,UNION結果,聚合它們並計算最高排名。

SELECT Id, [Name], Street, City, SUM([Rank]) 
FROM 
(
    SELECT emp.Id, [Name], Street, City, [Rank] 
    FROM Employee emp 
    JOIN [Address] addr ON emp.Id = addr.EmployeeId 
    JOIN CONTAINSTABLE(Employee, *, 'JOHN OR Hamburg') AS keyTblEmp ON emp.Id = keyTblEmp.[KEY] 

    UNION ALL 

    SELECT emp.Id, [Name], Street, City, [Rank] 
    FROM Employee emp 
    JOIN [Address] addr ON emp.Id = addr.EmployeeId 
    JOIN CONTAINSTABLE([Address], *, 'JOHN OR Hamburg') AS keyTblAdd ON addr.Id = keyTblAdd.[KEY] 
) as tmp 

GROUP BY Id, [Name], Street, City 
ORDER BY SUM([Rank]) DESC 

這是不太理想,這裏就是你的例子(你的情況,你會從漢堡想李四先出現):

Id  Name    Street   City   Rank 
2  John Smith  Hamburg St.  Springville 112 
3  Bob Hamburg  St. John Ave.  Springville 112 
5  John Doe   Oak Lane   Hamburg  96 
1  John Hamburg  Main St.   Springville 48 
4  Bob Smith   5th Ave.   Hamburg  48 

但這是最好的,你可以在提交給SQL之前解析輸入,以便根據用戶的需求做出「最佳猜測」。

+1

感謝您的回覆。我想保留一個輸入框,因爲用戶應該很容易在Google中搜索真正快速的內容。如果用戶搜索約翰漢堡,他想要得到結果 約翰誰住在漢堡 約翰誰的姓可能是漢堡和誰可能住在漢堡 但沒有結果 只是約翰誰不住在漢堡。 或者住在漢堡的其他人。 事情是,稍後會有更多的信息可以像電子郵件等搜索。因此,我需要一個包含所有數據一次包含由AND連接的術語的containstable。 – Chris 2010-01-13 22:51:29

+0

回到語法。如果您不知道輸入關鍵字應該應用於哪個表和列,則無法在大量邏輯中進行編程而無法創建「通用」AND語句。在上面的例子中,您如何知道將第一個關鍵字搜索爲[Name],將第二個關鍵字搜索爲[City]?如果用戶希望第二個關鍵字成爲名稱的一部分,或者是街道的一部分,該怎麼辦?除非你有一些你沒有提到的語法規則,否則這些規則說明了什麼「第一個詞將是一個名字,第二個詞將是一個城市」? – GalacticJello 2010-01-14 16:21:56

+0

@Chris每當我看到「像Google一樣」這個短語時,我的回答總是一樣的:如果在Google上創建'like'邏輯很容易在stackoverflow上回答,那麼他們就不會聘用數千名高薪的開發者。不要指望能夠在短短几天內複製這種質量。 – ean5533 2011-12-07 14:48:43