En esta página se describe cómo añadir tokenización a las tablas. La tokenización es necesaria para crear los tokens que se usan en el índice de búsqueda.
La tokenización es el proceso de transformar valores en tokens. El método que uses para tokenizar un documento determina los tipos y la eficiencia de las búsquedas que los usuarios pueden realizar en él.
Spanner proporciona tokenizadores para texto en lenguaje natural, subcadenas, texto literal, números y valores booleanos. El esquema de la base de datos usa el tokenizador que coincide con el tipo de búsqueda necesario para la columna. Los tokenizadores tienen las siguientes características:
- Cada tokenizador es una función de SQL que recibe una entrada, como una cadena o un número, y argumentos con nombre para opciones adicionales.
- El tokenizador genera un
TOKENLIST
.
Por ejemplo, la cadena de texto The quick brown fox jumps over the lazy dog
se tokeniza como [the,quick,brown,fox,jumps,over,the,lazy,dog]
.
Una cadena HTML The <b>apple</b> is <i>red</i>
se tokeniza en
[the,apple,is,red]
.
Los tokens tienen las siguientes características:
- Los tokens se almacenan en columnas que usan el tipo de datos
TOKENLIST
. - Cada token se almacena como una secuencia de bytes, con un conjunto opcional de atributos asociados. Por ejemplo, en las aplicaciones de texto completo, un token suele ser una sola palabra de un documento de texto.
- Al tokenizar valores HTML, Spanner genera atributos que indican la importancia de un token en el documento. Spanner usa estos atributos para asignar puntuaciones y destacar los términos más importantes (como un encabezado).
Tokenizadores
Spanner admite las siguientes funciones de tokenización:
El tokenizador de texto completo (
TOKENIZE_FULLTEXT
) genera tokens de palabras completas para las consultas en lenguaje natural.Ejemplo
Ambas funciones:
GoogleSQL
TOKENIZE_FULLTEXT("Yellow apple") TOKENIZE_FULLTEXT("Yellow <b>apple</b>", content_type=>"text/html")
PostgreSQL
En este ejemplo se usa
spanner.tokenize_fulltext
.spanner.tokenize_fulltext("Yellow apple") spanner.tokenize_fulltext('Yellow <b>apple</b>', context_type=>'text/html')
producen los mismos tokens:
[yellow,apple]
.Tokenizador de subcadenas (
TOKENIZE_SUBSTRING
) genera tokens para cada n-grama de cada palabra. Se usa para buscar subcadenas de palabras en un texto.Ejemplo
GoogleSQL
TOKENIZE_SUBSTRING('hello world', ngram_size_min=>4, ngram_size_max=>6)
PostgreSQL
En este ejemplo se usa
spanner.tokenize_substring
.spanner.tokenize_substring('hello world', ngram_size_min=>4, ngram_size_max=>6)
Produce los siguientes tokens:
[ello,hell,hello,orld,worl,world]
.Tokenizador de n-gramas (
TOKENIZE_NGRAMS
) genera n-gramas a partir de una entrada (sin dividirla en palabras independientes). Se usa para acelerar los predicados de expresiones regulares.Ejemplo
La siguiente función:
GoogleSQL
TOKENIZE_NGRAMS("Big Time", ngram_size_min=>4, ngram_size_max=>4)
PostgreSQL
En este ejemplo se usa
spanner.tokenize_ngrams
.spanner.tokenize_ngrams('big time', ngram_size_min=>4, ngram_size_max=>4)
Produce los siguientes tokens:
["Big ","ig T","g Ti"," Tim", "Time"]
.Los tokenizadores de concordancia exacta (
TOKEN
yTOKENIZE_BOOL
) se usan para buscar filas que contengan un valor determinado en una de sus columnas. Por ejemplo, una aplicación que indexe un catálogo de productos puede querer buscar productos de una marca y un color concretos.Ejemplos
Las siguientes funciones:
GoogleSQL
TOKEN("hello") TOKEN(["hello", "world"])
PostgreSQL
En este ejemplo se usa
spanner.token
.spanner.token('hello')
Produce los siguientes tokens:
[hello]
.La siguiente función:
GoogleSQL
TOKENIZE_BOOL(true)
PostgreSQL
En este ejemplo se usa
spanner.tokenize_bool
.spanner.tokenize_bool(true)
Genera el siguiente token:
[y]
.Los tokenizadores de números (
TOKENIZE_NUMBER
) se usan para generar un conjunto de tokens que aceleran las búsquedas de comparación numérica. En las condiciones de igualdad, el token es el propio número. En el caso de las condiciones de intervalo (comorating >= 3.5
), el conjunto de tokens es más elaborado.Ejemplos
Las siguientes declaraciones de funciones:
GoogleSQL
TOKENIZE_NUMBER(42, comparison_type=>'equality') TOKENIZE_NUMBER(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)
PostgreSQL
En este ejemplo se usa
spanner.tokenize_number
.spanner.tokenize_number(42, comparison_type=>'equality') spanner.tokenize_number(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)
Genera los siguientes tokens, respectivamente:
"==42"
y"==42"
,"[1,75]"
,"[36, 45]"
,"[36,55]"
,"[36, 75]"
.Los tokenizadores JSON y JSONB (
TOKENIZE_JSON
yTOKENIZE_JSONB
se usan para generar un conjunto de tokens que aceleran los predicados de contención de JSON y de existencia de claves, comodoc[@key] IS NOT NULL
(GoogleSQL) odoc ? 'key'
(PostgreSQL).
Las funciones de tokenización se suelen usar en una expresión de columna generada. Estas columnas se definen como HIDDEN
para que no se incluyan en los resultados de las consultas SELECT *
.
En el siguiente ejemplo se usan un tokenizador de texto completo y un tokenizador numérico para crear una base de datos que almacene nombres y valoraciones de álbumes de música. La instrucción DDL hace dos cosas:
- Define las columnas de datos
AlbumTitle
yRating
. Define
AlbumTitle_Tokens
yAlbumRating_Tokens
. EstasTOKENLIST
columnas tokenizan los valores de las columnas de datos para que Spanner pueda indexarlos.GoogleSQL
CREATE TABLE Albums ( AlbumId STRING(MAX) NOT NULL, AlbumTitle STRING(MAX), Rating FLOAT64, AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN, Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN ) PRIMARY KEY(AlbumId);
PostgreSQL
CREATE TABLE albums ( albumid character varying NOT NULL, albumtitle character varying, albumtitle_Tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN, PRIMARY KEY(albumid));
Cada vez que se modifican los valores base, AlbumTitle_Tokens
y Rating_Tokens
se actualizan automáticamente.
Tokenizar contenido de texto sin formato o HTML
La tokenización de texto admite tipos de contenido de texto sin formato y HTML. Usa la función
Spanner TOKENIZE_FULLTEXT
para crear tokens. A continuación, usa la instrucción DDL CREATE SEARCH INDEX
para generar el índice de búsqueda.
Por ejemplo, la siguiente declaración de DDL de CREATE TABLE
usa la función TOKENIZE_FULLTEXT
para crear tokens a partir de AlbumTitles
en la tabla Albums
. La instrucción DDL CREATE SEARCH INDEX
crea un índice de búsqueda con el nuevo AlbumTitles_Tokens
.
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex ON Albums(AlbumTitle_Tokens)
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex ON albums(albumtitle_tokens)
El proceso de tokenización sigue estas reglas:
- La tokenización no incluye la raíz ni la corrección de las palabras con errores ortográficos. Por ejemplo, en una frase como "Un gato estaba mirando a un grupo de gatos", el token "gato" se indexa por separado del token "gatos". En comparación con otros buscadores que normalizan los tokens durante las escrituras, Spanner ofrece una opción para ampliar la consulta de búsqueda e incluir diferentes formas de las palabras. Para obtener más información, consulta el artículo sobre el modo de consulta mejorado.
- Las palabras de parada (como "a") se incluyen en el índice de búsqueda.
- La búsqueda en todo el texto no distingue entre mayúsculas y minúsculas. El proceso de tokenización convierte todos los tokens a minúsculas.
El proceso de tokenización registra las posiciones de cada token en el texto original. Estas posiciones se usan más adelante para buscar coincidencias de frases. Las posiciones se almacenan en el índice de búsqueda junto con los docids.
Google sigue mejorando los algoritmos de tokenización. En algunos casos, esto puede provocar que una cadena se tokenice de forma diferente en el futuro con respecto a cómo se tokeniza ahora. Esperamos que estos casos sean extremadamente raros. Por ejemplo, si se mejora la segmentación de los idiomas chino, japonés y coreano (CJK).
El argumento content_type
especifica si el formato del contenido usa texto sin formato o HTML. Utiliza los siguientes ajustes para configurar el content_type
:
- Para la tokenización de texto, asigna el valor "
text/plain
" al argumentocontent_type
. Este es el ajuste predeterminado. - Para la tokenización de HTML, asigna el valor
"text/html
" al argumentocontent_type
. Sin este argumento, las etiquetas HTML se tratan como signos de puntuación. En el modo HTML, Spanner usa heurísticas para inferir la prominencia del texto en la página. Por ejemplo, si el texto está en un encabezado o el tamaño de su fuente. Los atributos admitidos para HTML sonsmall
,medium
,large
,title
y `link'. Al igual que la posición, el atributo se almacena junto con el token en el índice de búsqueda. La tokenización no crea tokens para ninguna etiqueta HTML.
Los atributos de token no influyen en las coincidencias ni en los resultados de las funciones SEARCH
o SEARCH_SUBSTRING
. Solo se usan para clasificar.
En el siguiente ejemplo se muestra cómo tokenizar texto:
GoogleSQL
CREATE TABLE T (
...
Text STRING(MAX),
Html STRING(MAX),
Text_Tokens TOKENLIST
AS (TOKENIZE_FULLTEXT(Text, content_type=>"text/plain")) HIDDEN,
Html_Tokens TOKENLIST
AS (TOKENIZE_FULLTEXT(Html, content_type=>"text/html")) HIDDEN
) PRIMARY KEY(...);
PostgreSQL
CREATE TABLE t (
...
text character varying,
html character varying,
text_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(text, content_type=>"text/plain")) VIRTUAL HIDDEN,
html_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(html, content_type=>'type/html')) VIRTUAL HIDDEN,
PRIMARY KEY(...));
Refinar la detección de idioma con el argumento language_tag
La tokenización detecta el idioma de entrada automáticamente de forma predeterminada. Cuando se conoce el idioma de entrada, se puede usar un argumento language_tag
para refinar este comportamiento:
GoogleSQL
AlbumTitle_Tokens TOKENLIST
AS (TOKENIZE_FULLTEXT(AlbumTitle, language_tag=>"en-us")) HIDDEN
PostgreSQL
albumtitle_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle, language_tag=>'en-us')) VIRTUAL HIDDEN
La mayoría de las aplicaciones no especifican el argumento language_tag
y, en su lugar, utilizan la detección automática de idiomas. Para segmentar por idiomas asiáticos, como el chino, el coreano y el japonés, no es necesario definir el idioma de tokenización.
En los siguientes ejemplos se muestran casos en los que language_tag
afecta a la tokenización:
Función de tokenización | Tokens producidos |
---|---|
TOKENIZE_FULLTEXT("A tout pourquoi il y a un parce que") |
[a, tout, pourquoi, il, ya, un, parce, que] |
TOKENIZE_FULLTEXT("A tout pourquoi il y a un parce que", \ language_tag=>"fr" ) |
[a, tout, pourquoi, il, y, a, un, parce, que] |
TOKENIZE_FULLTEXT("旅 行") |
Dos tokens: [旅, 行] |
TOKENIZE_FULLTEXT("旅 行", language_tag=>"zh") |
Un token: [旅行] |
Siguientes pasos
- Consulta información sobre los índices de búsqueda.
- Consulta información sobre los índices numéricos.
- Consulta información sobre la partición de índices.