Cette page décrit la fonction SEARCH
et le mode de requête amélioré, qui sont
permettant d'effectuer une recherche en texte intégral
sur les tables Spanner.
Interroger un index de recherche
Spanner fournit
SEARCH
à utiliser pour les requêtes d'index de recherche. Un exemple de cas d'utilisation serait
application dans laquelle les utilisateurs saisissent du texte dans un champ de recherche et l'application
envoie l'entrée utilisateur directement dans la fonction SEARCH
. La fonction SEARCH utiliserait ensuite un indice de recherche pour trouver ce texte.
La fonction SEARCH
nécessite deux arguments:
- Nom d'un index de recherche
- Requête de recherche brute
La fonction SEARCH
ne fonctionne que lorsqu'un index de recherche est défini. SEARCH
peut être combinée à n'importe quelle construction SQL arbitraire, telle que des filtres,
des agrégations ou des jointures.
La fonction SEARCH
ne peut pas être utilisée avec des requêtes de transaction.
La requête suivante utilise la fonction SEARCH
pour renvoyer tous les albums dont le titre contient friday
ou monday
:
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')
Requêtes de recherche brutes et langage rquery
Le deuxième argument de la fonction SEARCH
est une requête de recherche brute.
Spanner utilise un langage spécifique au domaine (DSL) appelé rquery.
Le langage rquery suit les mêmes règles que l'analyseur lexical en texte brut lors de la division de la chaîne d'entrée en termes distincts. Cela inclut la segmentation des langues asiatiques.
Pour en savoir plus sur l'utilisation de rquery, consultez syntaxe rquery.
Mode Requête amélioré
Spanner propose deux modes de recherche en texte intégral: un mode de recherche de base
la recherche Google et un mode plus avancé appelé enhance_query
. Lorsque cette option est activée,
enhance_query
étend la requête de recherche pour y inclure des termes associés et des synonymes,
ce qui augmente la probabilité de trouver des résultats pertinents.
Pour activer cette option, définissez l'argument facultatif enhance_query=>true
dans la fonction SEARCH
. Par exemple, la requête de recherche hotl cal
correspond à l'album Hotel California
.
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)
Le mode enhance_query
est une option au moment de la requête. Cela n'a aucune incidence sur la tokenisation.
Vous pouvez utiliser le même index de recherche avec ou sans enhance_query
.
Google améliore constamment ses algorithmes d'amélioration des requêtes. Par conséquent, une requête avec enhance_query == true
peut générer des résultats légèrement différents au fil du temps.
Lorsque le mode enhance_query
est activé, cela peut augmenter le nombre de termes
recherchée par la fonction SEARCH
, ce qui pourrait légèrement augmenter la latence.
Par exemple, la requête suivante utilise un délai avant expiration de trois secondes et échoue si enhance_query
n'est pas disponible :
@{require_enhance_query=true, enhance_query_timeout_ms=3000}
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'fast car', enhance_query=>true)
Pour en savoir plus sur l'utilisation de l'option enhance_query
, consultez la fonction SEARCH.
Exigences concernant les requêtes SQL
Une requête SQL doit remplir plusieurs conditions pour utiliser un indice de recherche. Si ces conditions ne sont pas remplies, la requête utilise un autre plan de requête ou échoue si aucun autre plan n'existe.
Les requêtes doivent remplir les conditions suivantes:
Les fonctions
SEARCH
etSEARCH_SUBSTRING
nécessitent un index de recherche. Spanner n'est pas compatible avec ces fonctions dans les requêtes adressées à la table de base ou aux index secondaires.Pour les index partitionnés, toutes les colonnes de partition doivent être liées par une condition d'égalité dans la clause
WHERE
de la requête.Par exemple, si un indice de recherche est défini sur
PARTITION BY x, y
, la requête doit comporter un conjoncteur dans la clauseWHERE
dex = <parameter or constant> AND y = <parameter or constant>
. Cet index de recherche pris en compte par l'optimiseur de requêtes si une telle condition est manquante.Toutes les colonnes
TOKENLIST
référencées par les opérateursSEARCH
etSEARCH_SUBSTRING
doivent être indexées dans le même indice de recherche.Prenons l'exemple de la définition de table et d'index suivante:
CREATE TABLE Albums ( AlbumId STRING(MAX) NOT NULL, AlbumTitle STRING(MAX), AlbumStudio STRING(MAX), AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN, AlbumStudio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumStudio)) HIDDEN ) PRIMARY KEY(AlbumId); CREATE SEARCH INDEX AlbumsTitleIndex ON Albums(AlbumTitle_Tokens); CREATE SEARCH INDEX AlbumsStudioIndex ON Albums(AlbumStudio_Tokens);
La requête suivante échoue, car aucun index de recherche unique n'est indexe à la fois
AlbumTitle_Tokens
etAlbumStudio_Tokens
:SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)
Si la colonne d'ordre de tri est nullable, le schéma et la requête doivent exclure les lignes où la colonne d'ordre de tri est NULL. Pour en savoir plus, consultez la section Ordre de tri de l'index de recherche.
Si l'index de recherche est filtré NULL, la requête doit inclure le même Expression de filtrage NULL utilisée dans un index. Pour en savoir plus, consultez la section Index de recherche filtré par NULL.
Les index de recherche et les fonctions de recherche ne sont pas compatibles avec le langage LMD, le langage LMD partitionné ni les requêtes partitionnées.
Les index de recherche et les fonctions de recherche sont généralement utilisés dans les transactions en lecture seule. Si les exigences de l'application autorisent les résultats obsolètes, nous vous recommandons d'exécuter des requêtes de recherche avec une durée d'obsolescence d'au moins 10 secondes. Pour en savoir plus, consultez la section Lire des données obsolètes. C'est particulièrement utile pour les requêtes de recherche volumineuses qui sont distribuées vers plusieurs Paxos groupes.
Les index de recherche et les fonctions de recherche ne sont pas recommandés dans les transactions en lecture-écriture. Pendant l'exécution, les requêtes de recherche verrouillent l'intégralité d'une partition d'index. en tant que Résultat, un taux élevé de requêtes de recherche dans les transactions en lecture-écriture peut entraîner des conflits de verrouillage entraînant des pics de latence. Par défaut, les index de recherche automatiquement sélectionné dans les transactions en lecture/écriture. Si une requête est obligée de utilise un index de recherche dans une transaction en lecture-écriture, il échoue par défaut. Il va échouent également si la requête contient l'une des fonctions de recherche. Ce comportement peut être ignoré avec l'indice au niveau de l'instruction
@{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE}
(mais les requêtes sont toujours sujettes à des conflits de verrouillage).
Une fois que les conditions d'éligibilité de l'index sont remplies, l'optimiseur de requêtes tente d'accélérer les conditions de requête non textuelles (comme Rating > 4
). Si l'index de recherche n'inclut pas la colonne TOKENLIST
appropriée, la condition n'est pas accélérée et reste une condition résiduelle.
Paramètres de requête
rquery et d'autres paramètres tels que OFFSET
sont spécifiés sous la forme d'un littéral ou
Un paramètre de requête.
Nous vous recommandons d'utiliser des paramètres de requête pour la recherche dans le texte intégral plutôt que des littéraux de chaîne.
Sélection d'index
Spanner sélectionne généralement l'index le plus efficace pour une requête
à l'aide de la modélisation basée sur les coûts. Cependant, la suggestion FORCE_INDEX
indique explicitement
Spanner pour utiliser un index de recherche spécifique. Par exemple, l'exemple suivant montre comment forcer Spanner à utiliser AlbumsIndex
:
SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
Si l'index de recherche spécifié n'est pas éligible, la requête échoue, même si d'autres index de recherche éligibles sont disponibles.
Extraits dans les résultats de recherche
Un extrait est un texte extrait d'une chaîne donnée qui donne aux utilisateurs une une idée du contenu d'un résultat de recherche et de la raison pour laquelle il est pertinentes par rapport à leur requête.
Par exemple, Gmail utilise des extraits pour indiquer la partie d'un e-mail qui correspond à la requête de recherche :
Le fait que la base de données génère un extrait présente plusieurs avantages:
- Pratique : vous n'avez pas besoin d'implémenter de logique pour générer des extraits à partir d'une requête de recherche.
- Efficacité : les extraits réduisent la taille de sortie du serveur.
La fonction SNIPPET
crée l'extrait. Elle renvoie la partie pertinente
la valeur de la chaîne d'origine ainsi que les positions
des caractères à mettre en surbrillance. La
le client peut ensuite choisir comment présenter l'extrait de code à l'utilisateur final (par exemple,
en utilisant du texte en surbrillance ou en gras). La fonction SNIPPET
supprime toutes les balises HTML de la chaîne d'origine.
Par exemple, la commande suivante utilise SNIPPET
pour récupérer du texte à partir de AlbumTitle
:
SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")
Étape suivante
- Découvrez comment classer les résultats de recherche.
- Découvrez comment effectuer une recherche de sous-chaîne.
- Découvrez comment paginer les résultats de recherche.
- Découvrez comment combiner des requêtes de texte complet et non textuelles.
- Découvrez comment effectuer une recherche dans plusieurs colonnes.