2017-05-08 56 views
0

我一直在努力让我的脑海围绕SQL Server全文搜索如何排名我的结果。使用跨多列的FREETEXTTABLE SQL Server排名奇怪

考虑以下FREETEXTTABLE搜索:

DECLARE @SearchTerm varchar(55) = 'Peter Alex' 

SELECT ftt.[RANK], v.* 
FROM FREETEXTTABLE (vMembersFTS, (Surname, FirstName, MiddleName, MemberRef, Passport), @SearchTerm) ftt 
INNER JOIN vMembersFTS v ON v.ID = ftt.[KEY] 
ORDER BY ftt.[RANK] DESC; 

这将返回以下结果和排名情况:

enter image description here

RANK ID MemberRef Passport FirstName MiddleName Surname Salutation 
----- ---- ---------- ----------- ----------- ------------ ---------- ------------ 
18 2 AB-002     Pete      Peters  
18 9 AB-006     George     Alex  Mr Alex 
18 13 AB-009     Peter  David  Alex  Mr Alex 
14 3 AB-003     Peter  Alex   Jones     

正如你可以从上面贴的结果告诉,最后一排,虽然有,我认为,在'彼得''亚历克斯',出现在只有14的排名,其中第一排的结果只有一个匹配'彼得'(不可否认的是'彼得斯')。

这是一个人为的例子,但有些方式可以说明我的挫折和缺乏知识。

我花了相当多的时间研究,但我现在感觉有点超出我的深度。我确信我正在做一些愚蠢的事情,比如搜索多个专栏。

我欢迎您的帮助和支持。提前致谢。

感谢,

凯恩

(顺便说一句,我使用SQL Server 2012)

这里是SQL,您可以使用自己重复测试:

-- Create the Contacts table. 
CREATE TABLE dbo.Contacts 
(
    ID   int   NOT NULL PRIMARY KEY, 
    FirstName varchar(55) NULL, 
    MiddleName varchar(55) NULL, 
    Surname  varchar(55) NOT NULL, 
    Salutation varchar(55) NULL, 
    Passport varchar(55) NULL 
); 
GO 

-- Create the Members table. 
CREATE TABLE dbo.Members 
(
    ContactsID int   NOT NULL PRIMARY KEY, 
    MemberRef varchar(55) NOT NULL 
); 
GO 

-- Create the FTS view. 
CREATE VIEW dbo.vMembersFTS WITH SCHEMABINDING AS 
SELECT c.ID, 
     m.MemberRef, 
     ISNULL(c.Passport, '') AS Passport, 
     ISNULL(c.FirstName, '') AS FirstName, 
     ISNULL(c.MiddleName, '') AS MiddleName, 
     c.Surname, 
     ISNULL(c.Salutation, '') AS Salutation 
FROM dbo.Contacts c 
INNER JOIN dbo.Members AS m ON m.ContactsID = c.ID 
GO 

-- Create the view index for FTS. 
CREATE UNIQUE CLUSTERED INDEX IX_vMembersFTS_ID ON dbo.vMembersFTS (ID); 
GO 

-- Create the FTS catalogue and stop-list. 
CREATE FULLTEXT CATALOG ContactsFTSCatalog WITH ACCENT_SENSITIVITY = OFF; 
CREATE FULLTEXT STOPLIST ContactsSL FROM SYSTEM STOPLIST; 
GO 

-- Create the member full-text index. 
CREATE FULLTEXT INDEX ON dbo.vMembersFTS 
    (Surname, Firstname, MiddleName, Salutation, MemberRef, Passport) 
KEY INDEX IX_vMembersFTS_ID 
ON ContactsFTSCatalog 
WITH STOPLIST = ContactsSL; 
GO 



-- Insert some data. 
INSERT INTO Contacts VALUES (1, 'John', NULL, 'Smith', NULL, NULL); 
INSERT INTO Contacts VALUES (2, 'Pete', NULL, 'Peters', NULL, NULL); 
INSERT INTO Contacts VALUES (3, 'Peter', 'Alex', 'Jones', NULL, NULL); 
INSERT INTO Contacts VALUES (4, 'Philip', NULL, 'Smith', NULL, NULL); 
INSERT INTO Contacts VALUES (5, 'Harry', NULL, 'Dukes', NULL, NULL); 
INSERT INTO Contacts VALUES (6, 'Joe', NULL, 'Jones', NULL, NULL); 
INSERT INTO Contacts VALUES (7, 'Alex', NULL, 'Phillips', 'Mr Phillips', NULL); 
INSERT INTO Contacts VALUES (8, 'Alexander', NULL, 'Paul', 'Alex', NULL); 
INSERT INTO Contacts VALUES (9, 'George', NULL, 'Alex', 'Mr Alex', NULL); 
INSERT INTO Contacts VALUES (10, 'James', NULL, 'Castle', NULL, NULL); 
INSERT INTO Contacts VALUES (11, 'John', NULL, 'Alexander', NULL, NULL); 
INSERT INTO Contacts VALUES (12, 'Robert', NULL, 'James', 'Mr James', NULL); 
INSERT INTO Contacts VALUES (13, 'Peter', 'David', 'Alex', 'Mr Alex', NULL); 
INSERT INTO Members VALUES (1, 'AB-001'); 
INSERT INTO Members VALUES (2, 'AB-002'); 
INSERT INTO Members VALUES (3, 'AB-003'); 
INSERT INTO Members VALUES (5, 'AB-004'); 
INSERT INTO Members VALUES (8, 'AB-005'); 
INSERT INTO Members VALUES (9, 'AB-006'); 
INSERT INTO Members VALUES (11, 'AB-007'); 
INSERT INTO Members VALUES (12, 'AB-008'); 
INSERT INTO Members VALUES (13, 'AB-009'); 



-- Run the FTS query. 
DECLARE @SearchTerm varchar(55) = 'Peter Alex' 
SELECT ftt.[RANK], v.* 
FROM FREETEXTTABLE (vMembersFTS, (Surname, FirstName, MiddleName, MemberRef, Passport), @SearchTerm) ftt 
INNER JOIN vMembersFTS v ON v.ID = ftt.[KEY] 
ORDER BY ftt.[RANK] DESC; 

回答

0

排名根据您的查询中的订单进行分配:

DECLARE @SearchTerm varchar(55) = 'Peter Alex' 
SELECT ftt.[RANK], v.* 
FROM FREETEXTTABLE (vMembersFTS, (Surname, FirstName, MiddleName, MemberRef, Passport), @SearchTerm) ftt 
INNER JOIN vMembersFTS v ON v.ID = ftt.[KEY] 
ORDER BY ftt.[RANK] DESC; 

因此,在您的情况下,SurName上的匹配胜过FirstName,并且都是王牌MiddleName。

您的前3名结果的排名为18,因为所有三个匹配的姓氏。最后一条记录在FirstName和MiddleName上匹配的排名为14,但不匹配SurName。

您可以在这里的排名计算发现细节:https://technet.microsoft.com/en-us/library/ms142524(v=sql.105).aspx

如果你想相同的权重分配到这些,你可以,但你不得不使用CONTAINSTABLE而不是FREETEXTTABLE

信息可以在这里找到:https://technet.microsoft.com/en-us/library/ms189760(v=sql.105).aspx