Citation :
Accès aux données relationnelles et modification
Utilisation des fonctions CONTAINSTABLE et FREETEXTTABLE pour l'évaluation de l'ensemble des lignes
Les fonctions CONTAINSTABLE et FREETEXTTABLE sont utilisées pour spécifier les requêtes de texte intégral qui renvoient les rangs de valeurs appropriés pour chaque ligne. Ces fonctions sont très similaires, mais utilisées différemment à partir des prédicats de texte intégral, CONTAINS et FREETEXT.
Différentiation entre les prédicats de texte intégral et les fonctions
Bien que les prédicats de texte intégral et les fonctions d'évaluation de l'ensemble de lignes de texte intégral soient utilisés pour les requêtes de texte intégral et que l'instruction Transact-SQL servant à spécifier la condition de recherche de texte intégral soit à la fois la même pour les prédicats et les fonctions, il existe cependant des différences majeures quant à leur utilisation : CONTAINS et FREETEXT renvoient tous deux les valeurs TRUE ou FALSE, par conséquent, ils sont habituellement spécifiés dans la clause WHERE d'une instruction SELECT. CONTAINSTABLE et FREETEXTTABLE renvoient tous deux une table de zéro ligne, une ligne ou davantage ; par conséquent, elles doivent toujours être spécifiées dans la clause FROM.
CONTAINS et FREETEXT peuvent uniquement être utilisés pour spécifier les critères de sélection que Microsoft® SQL Server utilise pour déterminer l'appartenance du jeu de résultats. CONTAINSTABLE et FREETEXTTABLE sont également utilisées pour spécifier des critères de sélection. La table renvoyée possède une colonne appelée KEY qui comporte les valeurs des clés de texte intégral. Chaque table inscrite de texte intégral possède une colonne dont les valeurs sont assurées d'être uniques. Les valeurs renvoyées dans la colonne KEY de CONTAINSTABLE ou de FREETEXTTABLE constituent les valeurs uniques, de la table inscrite en texte intégral, des lignes qui correspondent aux critères de sélection spécifiés dans la condition de recherche de texte intégral.
De plus, la table produite par CONTAINSTABLE et FREETEXTTABLE possède une colonne nommée RANK, qui comporte des valeurs comprises entre 0 et 1000. Ces valeurs servent à attribuer des rangs aux lignes renvoyées, selon le degré de leur correspondance avec les critères de sélection.
Les requêtes utilisant les fonctions CONTAINSTABLE et FREETEXTTABLE sont plus complexes que celles qui font appel aux prédicats CONTAINS et FREETEXT, car les lignes sélectionnées renvoyées par ces fonctions, doivent être explicitement jointes avec les lignes figurant dans la table SQL Server d'origine.
L'exemple suivant renvoie la description et le nom de catégorie de toutes les catégories de produits alimentaires dont la colonne Description contient les mots « sweet and savory » à proximité du mot « sauces » ou « candies ». Toutes les lignes avec le nom de catégorie « Seafood » sont ignorées. Seules les lignes dont la valeur de classement est supérieure ou égale à 2 sont renvoyées. USE Northwind
GO
SELECT FT_TBL.Description, FT_TBL.CategoryName, KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
CONTAINSTABLE (Categories, Description, '("sweet and savory" NEAR sauces) OR
("sweet and savory" NEAR candies)'
) AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK > 2
AND FT_TBL.CategoryName <> 'Seafood'
ORDER BY KEY_TBL.RANK DESC
L'exemple suivant renvoie la description et le nom de catégorie des 10 premières catégories de produits alimentaires dont la colonne Description contient les mots « sweet and savory » à proximité du mot « sauces » ou « candies ». SELECT FT_TBL.Description, FT_TBL.CategoryName, KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
CONTAINSTABLE (Categories, Description, '("sweet and savory" NEAR sauces) OR
("sweet and savory" NEAR candies)'
, 10
) AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
Comparaison entre CONTAINSTABLE et CONTAINS
La fonction CONTAINSTABLE et le prédicat CONTAINS utilisent des conditions de recherche similaires. Cependant, dans CONTAINSTABLE, vous spécifiez la table qui fera l'objet de la recherche de texte intégral, la colonne (ou l'ensemble des colonnes) dans la table où effectuer la recherche, la colonne à rechercher et la condition de recherche. Un quatrième paramètre, facultatif, permet à l'utilisateur d'indiquer que seul le plus haut nombre spécifié de correspondances soit renvoyé. Pour plus d'informations, voir la rubrique « Limitation de jeux de résultats ».
CONTAINSTABLE renvoie une table qui comporte une colonne intitulée RANK. Cette colonne RANK contient une valeur pour chaque ligne, indiquant son degré de correspondance avec les critères de sélection.
Cette requête spécifie l'utilisation de CONTAINSTABLE pour renvoyer une valeur de rang pour chaque ligne.
USE Northwind
GO
SELECT K.RANK, CompanyName, ContactName, Address
FROM Customers AS C
INNER JOIN
CONTAINSTABLE(Customers,Address, 'ISABOUT ("des*",
Rue WEIGHT(0.5), Bouchers WEIGHT(0.9)
)
' ) AS K
ON C.CustomerID = K.[KEY]
Here is the result set:
RANK CompanyName ContactName address
---- ------------ ----------- -------
123 Bon app' Laurence Lebihan 12, rue des Bouchers 65 Du monde entier Janine Labrune 67, rue des Cinquante Otages 15 France restauration Carine Schmitt 54, rue Royale 15 La maison d'Asie Annette Roulet 1 rue Alsace-Lorraine
15 Maison Dewey Catherine Dewey Rue Joseph-Bens 532 15 Mère Paillarde Jean Fresnière 43 rue St. Laurent
15 Spécialités du monde Dominique Perrier 25, rue Lauriston 15 Vins et alcools Paul Henriot 59 rue de l'Abbaye
Chevalier
15 Victuailles en stock Mary Saveley 2, rue du Commerce
Comparaison entre FREETEXTTABLE et FREETEXT
La requête suivante étend une requête FREETEXTTABLE pour renvoyer les lignes des rangs les plus élevés en premier et ajouter ensuite le rang de chaque ligne à la liste de sélection. Pour spécifier une requête, il faut savoir que CategoryID constitue la colonne clé unique de la table Categories.
USE Northwind
GO
SELECT KEY_TBL.RANK, FT_TBL.Description
FROM Categories AS FT_TBL INNER JOIN
FREETEXTTABLE(Categories, Description,
'How can I make my own beers and ales?') AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
GO
The only difference in the syntax of FREETEXTTABLE and FREETEXT is the insertion of the table name as the first parameter.
Here is an extension of the same query that only returns rows with a rank value of 10 or greater:
USE Northwind
GO
SELECT KEY_TBL.RANK, FT_TBL.Description
FROM Categories FT_TBL INNER JOIN
FREETEXTTABLE (Categories, Description,
'How can I make my own beers and ales?') AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK >= 10
ORDER BY KEY_TBL.RANK DESC
GO
Identification du nom de colonne clé unique
Les requêtes qui utilisent les fonctions d'évaluation de l'ensemble de lignes s'avèrent complexes car il est nécessaire de connaître le nom de la colonne clé unique. Chaque table activée en mode texte intégral possède une propriété TableFulltextKeyColumn qui contient le numéro de l'ID de colonne de la colonne sélectionnée pour appliquer les lignes uniques de la table. L'exemple suivant montre comment le nom de la colonne clé peut être obtenu et utilisé de façon programmée.
USE Northwind
GO
DECLARE @key_column sysname
SET @key_column = Col_Name(Object_Id('Categories'),
ObjectProperty(Object_id('Categories'),
'TableFulltextKeyColumn') )
print @key_column
EXECUTE ('SELECT Description, KEY_TBL.RANK
FROM Categories FT_TBL INNER JOIN
FreetextTable (Categories, Description,
''How can I make my own beers and ales?'') AS KEY_TBL
ON FT_TBL.'
+
@key_column
+
' = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK >= 10
ORDER BY KEY_TBL.RANK DESC
')
GO
Il est possible de contourner la complexité liée à l'utilisation de CONTAINSTABLE et FREETEXTTABLE en écrivant des procédures stockées qui acceptent quelques faits à propos de la requête, puis créent et exécutent la requête appropriée. La procédure suivante est une procédure simplifiée soumettant une requête FREETEXTTABLE. Les paramètres de la procédure sont affichés dans la table (tous sont des paramètres d'entrée).
Paramètre Requis Description @additional_predicates Facultatif S'il y en a, ils seront ajoutés avec AND après le prédicat FREETEXT. KEY_TBL.RANK peut être employé dans des expressions.
@freetext_column Oui
@freetext_search Oui Condition de recherche @from_table Oui
@order_by_list Facultatif KEY_TBL.RANK peut être l'une des colonnes spécifiées. @select_list Oui KEY_TBL.RANK peut être l'une des colonnes spécifiées. Le code de la procédure est le suivant :
CREATE PROCEDURE freetext_rank_proc
@select_list nvarchar(1000),
@from_table nvarchar(517),
@freetext_column sysname,
@freetext_search nvarchar(1000),
@additional_predicates nvarchar(500) = '',
@order_by_list nvarchar(500) = ''
AS BEGIN
DECLARE @table_id integer,
@unique_key_col_name sysname,
@add_pred_var nvarchar(510),
@order_by_var nvarchar(510) -- Get the name of the unique key column for this table.
SET @table_id = Object_Id(@from_table)
SET @unique_key_col_name = Col_Name( @table_id, ObjectProperty(@table_id, 'TableFullTextKeyColumn') ) -- If there is an additional_predicate, put AND() around it.
IF @additional_predicates <> ''
SET @add_pred_var = 'AND (' + @additional_predicates + ')'
ELSE
SET @add_pred_var = ''
-- Insert ORDER BY, if needed.
IF @order_by_list <> ''
SET @order_by_var = 'ORDER BY ' + @order_by_var
ELSE
SET @order_by_var = ''
-- Execute the SELECT statement.
EXECUTE ( 'SELECT ' + @select_list
+ ' FROM '
+ @from_table
+ ' AS FT_TBL, FreetextTable('
+ @from_table
+ ','
+ @freetext_column
+ ','''
+ @freetext_search
+ ''') AS KEY_TBL '
+ 'WHERE FT_TBL.'
+ @unique_key_col_name
+ ' = KEY_TBL.[KEY] ' + @add_pred_var
+ ' '
+ @order_by_var
)
END
La procédure suivante peut être utilisée pour soumettre la requête :
USE Northwind
GO
EXECUTE freetext_rank_proc 'Description, KEY_TBL.RANK', -- Select list
'Categories', -- From
'Description', -- Column
'How can I make my own beers and ales?', -- Freetext search
'KEY_TBL.RANK >= 10', -- Additional predicate
'KEY_TBL.RANK DESC' -- Order by
GO
Limitation des jeux de résultats
Dans de nombreuses requêtes de texte intégral, le nombre d'éléments répondant aux critères de recherche est très important. Pour éviter que la requête ne renvoie un trop grand nombre de correspondances, utilisez l'argument facultatif, top_n_by_rank, dans CONTAINSTABLE et FREETEXTTABLE pour spécifier le nombre de correspondances d'après le classement que vous voulez en retour.
Avec ces informations, Microsoft® SQL Server trie les correspondances par rang et ne retourne que ceux compris dans le nombre spécifié. Ce choix peut considérablement améliorer les performances. Une requête qui devrait normalement renvoyer 100 000 lignes à partir d'une table en comprenant 1 million, par exemple, sera traitée plus rapidement si seules les 100 premières lignes sont requises.
Si vous voulez que les 3 premières correspondances soient renvoyées uniquement dans un exemple précédent à l'aide de CONTAINSTABLE, la requête doit être rédigée comme suit :
USE Northwind
GO
SELECT K.RANK, CompanyName, ContactName, Address
FROM Customers AS C
INNER JOIN
CONTAINSTABLE(Customers,Address, 'ISABOUT ("des*",
Rue WEIGHT(0.5),
Bouchers WEIGHT(0.9))', 3) AS K
ON C.CustomerID = K.[KEY]
Voici le jeu de résultats obtenu :
RANK CompanyName ContactName address
---- ------------ ----------- -------
123 Bon app' Laurence Lebihan 12, rue des Bouchers 65 Du monde entier Janine Labrune 67, rue des Cinquante Otages 15 France restauration Carine Schmitt 54, rue Royale
Voir aussi
CONTAINSTABLE
FREETEXTTABLE
©1988-2000 Microsoft Corporation. Tous droits réservés.
|