2016-11-02 110 views
3

我有一個要求,從客戶端有一個搜索字段,他想輸入任何文本和搜索該文本字段中的多個全文索引列包含客戶信息,來自客戶信息表。全文搜索多個搜索詞的多列

因此,舉例來說,如果他輸入FL Diana Brooks Miami 90210,他希望所有這些條款(FLDianaBrooksMiami90210)每個搜索進入狀態,名字,姓氏,城市和Zip列。

現在,這似乎完全是一個壞主意,作爲一個替代方案,我建議使用多個字段分別輸入這些信息。儘管如此,我的觀點是不得不作爲一個概念證明,爲什麼從性能的角度來看,這將無法正常工作,並且最好有多個字段輸入要搜索的術語。

因此,爲了獲得性能基準,我試圖寫一個全文查詢來完成客戶要求的內容。

我到目前爲止似乎沒有工作,所以我猜我問是否有可能做到這一點?

declare 
    @zip varchar(10)   = 90210 
    , @lastName varchar(50)  = 'Brooks' 
    , @firstName varchar(50) = 'Diana' 
    , @city varchar(50)   = 'Miami' 
    , @state char(2)   = 'FL' 
    , @searchTerm varchar(250) = '' 
    , @s varchar(1) = ' ' 

set @searchTerm = @state + ' ' + @firstName + ' ' + @lastName + ' ' + @city 

select * 
from freetexttable(contacts, (zip, lastName, FirstName, city, state), @searchTerm) ftTbl 
inner join contacts c on ftTbl.[key] = c.ContactID 

查詢我上面似乎工作,而不是爲了只找到我要找的單個記錄足夠的限制,並返回一大堆更多的(我猜這是因爲我正在使用FREETEXTTABLE)。

我也試圖與CONTAINSTABLE取代它,但我得到一個錯誤說:在

消息7630,級別15,狀態3,行26

語法錯誤附近 '黛安娜'全文檢索條件'佛羅里達黛安娜布魯克斯邁阿密'。

使用常規索引我已經能夠解決這個問題,但我很好奇,如果甚至可以用全文做同樣的事情。

使用常規索引我有一個適應的查詢的WHERE子句,如下圖所示:

WHERE C.FirstName like coalesce(@FirstName + '%' , C.FirstName) 
    AND C.LastName like coalesce(@LastName + '%' , C.LastName) 
    etc. 

回答

1

您可以創建一個視圖WITH SCHEMABINDINGid和串連列:

CREATE VIEW dbo.SearchView WITH SCHEMABINDING 
AS 
SELECT id, 
     [State]+' ', 
     [FirstName]+' ', 
     [LastName]+' ', 
     [City]+' ', 
     [Zip] as search_string 
FROM YourTable 

創建索引

CREATE UNIQUE CLUSTERED INDEX UCI_SearchView ON dbo.SearchView (id ASC) 

然後創建全文索引search_string字段。

USE YourDB 
GO 

--Enable Full-text search on the DB 
IF (SELECT DATABASEPROPERTY(DB_NAME(), N'IsFullTextEnabled')) <> 1 
EXEC sp_fulltext_database N'enable' 
GO 

--Create a full-text catalog 
IF NOT EXISTS (SELECT * FROM dbo.sysfulltextcatalogs WHERE [name] = N'CatalogName') 
EXEC sp_fulltext_catalog N'CatalogName', N'create' 
GO 

EXEC sp_fulltext_table N'dbo.SearchView', N'create', N'CatalogName', N'IndexName' 
GO 

--Add a column to catalog 
EXEC sp_fulltext_column N'dbo.SearchView', N'search_string', N'add', 0 /* neutral */ 
GO 

--Activate full-text for table/view 
EXEC sp_fulltext_table N'dbo.SearchView', N'activate' 
GO 

--Full-text index update 
exec sp_fulltext_catalog 'CatalogName', 'start_full' 
GO 

之後,你需要編寫一些函數來構造一個搜索條件。 F.E.

FL Diana Brooks Miami 90210 

變成了:

"FL*" AND "Diana*" AND "Brooks*" AND "Miami*" AND "90210*" 

而在FREETEXTCONTAINS搜索使用它:

DECLARE @search nvarchar(4000) = '"FL*" AND "Diana*" AND "Brooks*" AND "Miami*" AND "90210*"' 

SELECT sv.* 
FROM dbo.SearchView sv 
INNER JOIN CONTAINSTABLE (dbo.SearchView, search_string, @search) as c 
    ON c.[KEY] = sv.id 
+0

我剛剛找到你的答案後,我測試了類似的方法。我創建了一個連接所有搜索列的新列(有點冗餘,我知道 - 我更喜歡你的索引視圖),並使用了「WHERE CONTAINS(searchColumn,@searchTerm)」,它主要工作。我收到的唯一問題是,如果我在我的'@ searchTerm'變量中包含一個像'abc @ xyz.com'這樣的電子郵件地址,那麼電子郵件地址就會出現,我不會找回正確的一行。 –