2017-05-08 5 views
0

J'ai eu du mal à comprendre comment la recherche en texte intégral SQL Server classe mes résultats.Bizutage de classement SQL Server en utilisant FREETEXTTABLE sur plusieurs colonnes

Tenir compte de la FREETEXTTABLE recherche suivante:

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; 

Cela renvoie les résultats et les classements suivants:

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     

Comme vous pourriez être en mesure de dire à partir des résultats affichés ci-dessus, la dernière rangée, bien qu'ayant, ce que je considère, un bon match sur les deux 'Peter' et 'Alex', apparaît avec un rang de seulement 14 où le résultat dans la première rangée n'a qu'un seul match sur 'Peter' (il est vrai que le nom de famille est 'Peters').

Ceci est un exemple artificiel, mais illustre un peu mes frustrations et mon manque de connaissances.

J'ai passé pas mal de temps à faire des recherches, mais je me sens un peu hors de ma portée maintenant. Je suis sûr que je fais quelque chose de stupide comme la recherche sur plusieurs colonnes.

Je salue votre aide et votre soutien. Merci d'avance.

Merci,

Kaine

(BTW J'utilise SQL Server 2012)

Voici le SQL que vous pouvez utiliser pour répéter le test vous-même:

-- 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; 

Répondre

0

Le rang est l'assignation basée sur l'ordre dans votre requête:Donc, dans votre cas, une correspondance sur SurName l'emporte sur FirstName, et les deux surpassent MiddleName. Vos 3 premiers résultats ont un classement de 18 car tous les trois correspondent sur le nom de famille. Le dernier enregistrement a un rang de 14 pour la correspondance sur FirstName et MiddleName mais pas SurName.

Vous trouverez plus de détails sur les calculs de rang ici: https://technet.microsoft.com/en-us/library/ms142524(v=sql.105).aspx

Si vous souhaitez allouer un poids égal à ceux-ci, vous pouvez, mais vous devez utiliser CONTAINSTABLE et non FREETEXTTABLE.

Info peut être trouvé ici: https://technet.microsoft.com/en-us/library/ms189760(v=sql.105).aspx