2016-11-02 173 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'这样的电子邮件地址,那么电子邮件地址就会出现,我不会找回正确的一行。 –