Cette page explique comment utiliser une recherche proche dans le cadre d'une recherche dans le texte complet.
En plus d'effectuer des recherches de jetons exactes à l'aide des fonctions SEARCH
et SEARCH_SUBSTRING
, Spanner prend également en charge les recherches approximatives (ou floues). Les recherches approximatives trouvent des documents correspondants malgré de légères différences entre la requête et le document.
Spanner est compatible avec les types de recherche floue suivants:
- Recherche approximative basée sur les n-grammes
- Recherche phonétique à l'aide de Soundex
Utiliser une recherche approximative basée sur des n-grammes
La recherche floue basée sur les n-grammes repose sur la même tokenisation de sous-chaîne qu'une recherche de sous-chaîne. La configuration du tokenizer est importante, car elle affecte la qualité et les performances de recherche. L'exemple suivant montre comment créer une requête avec des mots mal orthographiés ou orthographiés différemment pour trouver des correspondances approximatives dans l'index de recherche.
Schéma
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (
TOKENIZE_SUBSTRING(AlbumTitle, ngram_size_min=>2, ngram_size_max=>3,
relative_search_types=>["word_prefix", "word_suffix"])) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens)
STORING (AlbumTitle);
Requête
La requête suivante recherche les albums dont les titres sont les plus proches de "Hatel Kaliphorn", comme "Hotel California".
SELECT AlbumId
FROM Albums
WHERE SEARCH_NGRAMS(AlbumTitle_Tokens, "Hatel Kaliphorn")
ORDER BY SCORE_NGRAMS(AlbumTitle_Tokens, "Hatel Kaliphorn") DESC
LIMIT 10
Optimiser les performances et la capacité de rappel pour une recherche approximative basée sur des n-grammes
L'exemple de requête de la section précédente effectue une recherche en deux phases, à l'aide de deux fonctions différentes:
SEARCH_NGRAMS
recherche tous les albums candidats qui ont partagé des n-grammes avec la requête de recherche. Par exemple, les n-grammes de trois caractères pour "Californie" incluent[cal, ali, lif, ifo, for, orn, rni, nia]
et pour "Kaliphorn" incluent[kal, ali, lip, iph, pho, hor, orn]
. Les n-grammes partagés dans ces ensembles de données sont[ali, orn]
. Par défaut,SEARCH_NGRAMS
fait correspondre tous les documents avec au moins deux n-grammes partagés. Par conséquent, "Kaliphorn" correspond à "Californie".SCORE_NGRAMS
classe les correspondances par similarité. La similarité de deux chaînes est définie comme un ratio de n-grammes partagés distincts par rapport aux n-grammes distincts non partagés:
En règle générale, la requête de recherche est la même pour les fonctions SEARCH_NGRAMS
et SCORE_NGRAMS
. La méthode recommandée consiste à utiliser l'argument avec des paramètres de requête plutôt qu'un littéral de chaîne, et à spécifier le même paramètre de requête dans les fonctions SEARCH_NGRAMS
et SCORE_NGRAMS
.
Spanner dispose de trois arguments de configuration pouvant être utilisés avec SEARCH_NGRAMS
:
- Taille minimale et maximale des n-grammes spécifiées dans
TOKENIZE_SUBSTRING
ouTOKENIZE_NGRAMS
. Nous vous déconseillons d'utiliser des n-grammes à un seul caractère, car ils correspondent à un très grand nombre de documents. En revanche, les n-grammes longs font queSEARCH_NGRAMS
ne détecte pas les mots courts mal orthographiés. - Nombre minimal d'n-grammes que
SEARCH_NGRAMS
doit faire correspondre (défini avec les argumentsmin_ngrams
etmin_ngrams_percent
dansSEARCH_NGRAMS
). Des valeurs plus élevées accélèrent généralement la requête, mais réduisent le rappel.
Pour obtenir un bon équilibre entre performances et rappel, ces arguments peuvent être configurés pour s'adapter à la requête et à la charge de travail spécifiques.
Nous vous recommandons également d'inclure un LIMIT
interne pour éviter de créer des requêtes très coûteuses lorsqu'une combinaison de n-grammes populaires est rencontrée:
SELECT AlbumId
FROM (
SELECT AlbumId,
SCORE_NGRAMS(AlbumTitle_Tokens, @p) AS score
FROM Albums
WHERE SEARCH_NGRAMS(AlbumTitle_Tokens, @p)
LIMIT 10000 # inner limit
)
ORDER BY score DESC
LIMIT 10 # outer limit
Recherche floue basée sur les n-grammes par rapport au mode de requête amélioré
En plus de la recherche approximative basée sur les n-grammes, le mode de requête amélioré gère également certains mots mal orthographiés. Il existe donc un chevauchement entre les deux fonctionnalités. Le tableau suivant récapitule les différences:
Recherche de correspondance partielle basée sur des n-grammes | Mode de requête amélioré | |
Coût | Nécessite une tokenisation de sous-chaîne plus coûteuse basée sur les n-grammes | Nécessite une tokenisation du texte complet moins coûteuse |
Types de requêtes de recherche | Fonctionne bien avec les documents courts de quelques mots, comme le nom d'une personne, d'une ville ou d'un produit | Fonctionne aussi bien avec des documents et des requêtes de recherche de n'importe quelle taille |
Recherche de mots partiels | Effectue une recherche de sous-chaîne qui permet les fautes d'orthographe | Ne prend en charge que la recherche de mots entiers (SEARCH_SUBSTRING n'est pas compatible avec l'argument enhance_query )
|
Mots mal orthographiés | Prise en charge des mots mal orthographiés dans l'index ou la requête | N'accepte que les mots mal orthographiés dans la requête |
Corrections | Recherche les correspondances mal orthographiées, même si elles ne correspondent pas à un mot réel | Corrige les fautes d'orthographe pour les mots courants et connus |
Effectuer une recherche phonétique avec Soundex
Spanner fournit la fonction SOUNDEX
pour trouver des mots qui s'écrivent différemment, mais qui se prononcent de la même manière. Par exemple, SOUNDEX("steven")
, SOUNDEX("stephen")
et SOUNDEX("stefan")
sont tous "s315", tandis que SOUNDEX("stella")
est "s340". SOUNDEX
est sensible à la casse et ne fonctionne que pour les alphabets latins.
La recherche phonétique avec SOUNDEX
peut être implémentée avec une colonne générée et un index de recherche, comme illustré dans l'exemple suivant:
CREATE TABLE Singers (
SingerId INT64,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
Name STRING(MAX),
NameSoundex STRING(MAX) AS (LOWER(SOUNDEX(Name))),
NameSoundex_Tokens TOKENLIST AS (TOKEN(NameSoundex)) HIDDEN
) PRIMARY KEY(SingerId);
CREATE SEARCH INDEX SingersPhoneticIndex ON Singers(AlbumTitle_Tokens, NameSoundex_Tokens);
La requête suivante fait correspondre "stefan" à "Steven" sur SOUNDEX
, avec AlbumTitle
contenant "cat":
SELECT SingerId
FROM Singers
WHERE NameSoundex = LOWER(SOUNDEX("stefan")) AND SEARCH(AlbumTitle_Tokens, "cat")
Étape suivante
- Découvrez la tokenisation et les tokenizers Spanner.
- En savoir plus sur les index de recherche
- En savoir plus sur les requêtes de recherche en texte intégral