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