1

我一直在努力弄清楚 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;

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

在此处输入图像描述

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                  

正如您可以从上面发布的结果中看出的那样,最后一行,尽管我认为在'Peter''Alex'上都很好匹配,但排名只有 14,而结果在第一row 在'Peter'上只有一个匹配项(诚然,姓氏是 'Peters')。

这是一个人为的例子,但在某种程度上说明了我的挫败感和缺乏知识。

我花了很多时间研究,但我现在感觉有点超出我的深度。我确定我正在做一些愚蠢的事情,例如跨多个列进行搜索。

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

谢谢,

凯恩

(顺便说一句,我使用的是 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;
4

1 回答 1

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 个结果在 Surname 上的所有三个匹配中的排名为 18。最后一条记录在 FirstName 和 MiddleName 但不是 SurName 上的匹配排名为 14。

您可以在此处找到有关排名计算的详细信息:https ://technet.microsoft.com/en-us/library/ms142524(v=sql.105).aspx

如果您想为这些分配相同的权重,您可以,但您必须使用CONTAINSTABLEand not FREETEXTTABLE

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

于 2017-05-08T15:17:05.070 回答