Combina TOKENLISTs

En esta página, se describe cómo concatenar TOKENLIST en un el índice de búsqueda cuando configuras el esquema o en una búsqueda cuando realices una búsqueda en el texto completo en Spanner.

Combinar TOKENLIST en un índice de búsqueda

A veces, necesitas que tu aplicación realice búsquedas en campos individuales. En otras veces, la aplicación debe buscar en todos los campos. Por ejemplo, en una tabla con dos columnas de cadena, es posible que desees que tu aplicación realice la búsqueda en ambas columnas sin diferenciar de qué columna provienen las coincidencias.

En Spanner, hay dos formas de lograrlo:

  1. Divide las palabras por separado y concatena los valores TOKENLIST resultantes (recomendado).
  2. Concatena cadenas y asigna un token al resultado.

Con el segundo enfoque, hay dos problemas:

  1. Si deseas indexar Title o Studio de forma individual, además de indexarlos en un TOKENLIST combinado, el mismo texto se segmenta dos veces. Esto hace que las transacciones usen más recursos.
  2. Una búsqueda de frase abarca ambos campos. Por ejemplo, si @p se establece en "Blue Note", coincide con una fila que contiene Title="Big Blue Note" y Studio="Blue Note Studios".

El primer enfoque resuelve estos problemas porque una frase solo coincide con un campo. y a cada campo de cadena solo se le asigna un token una vez si tanto el campo individual como TOKENLIST están indexadas. Aunque a cada campo de cadena solo se le asigna un token una vez, los TOKENLIST resultantes se almacenan por separado en el índice.

Asignar tokens a palabras por separado y concatenar valores TOKENLIST

En el siguiente ejemplo, se tokeniza cada palabra y se concatenan los valores TOKENLIST:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
  Combined_Tokens TOKENLIST AS (TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens])) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

La concatenación de TOKENLIST también se puede implementar por completo en el lado de la consulta. Para obtener más información, consulta Concatenación de TOKENLIST del lado de la consulta.

TOKENLIST_CONCAT es compatible con las búsquedas de texto completo y de subcadena. Spanner no te permite mezclar tipos de asignación de token, como TOKENIZE_FULLTEXT y TOKENIZE_SUBSTRING en el mismo TOKENLIST_CONCAT llamada.

La definición de las columnas de texto TOKENLIST se puede cambiar en las columnas no almacenadas para agregar columnas adicionales. Esto es útil cuando quieres agregar una columna adicional a TOKENLIST_CONCAT. Cambiar la expresión de la columna generada no reabastece las filas existentes en el índice.

Concatena cadenas y asigna un token al resultado

En el siguiente ejemplo, se concatenan cadenas y se asignan tokens al resultado:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Combined_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title || " " || Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

Cadena TOKENLIST del lado de la consulta

La desventaja de indexar el TOKENLIST concatenado es que aumenta de almacenamiento y escritura. Cada token ahora se almacena en el disco dos veces: una vez en una lista de publicaciones de su TOKENLIST original y una vez en una lista de publicaciones del TOKENLIST combinado. Concatenación de columnas TOKENLIST en el lado de la consulta evita este costo, pero la consulta usa más recursos de procesamiento.

Para concatenar varias TOKENLIST, usa la función TOKENLIST_CONCAT en la consulta SEARCH. En esta sección, usaremos el siguiente esquema de muestra:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Title_Tokens, Studio_Tokens);

La siguiente consulta busca filas que tengan los tokens "blue" y "note" en cualquier parte de las columnas Title y Studio. Esto incluye filas con "blue" y "note" en la columna Title, "blue" y "note" en la columna Studio, "blue" en la columna Title y "note" en la columna Studio, o lo opuesto.

SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')

La concatenación de TOKENLIST del lado de la escritura y del lado de la consulta produce resultados idénticos. La elección entre ambos es una compensación entre el costo del disco y el costo de la consulta.

Como alternativa, una aplicación podría buscar varias columnas TOKENLIST y usar OR junto con la función SEARCH:

SEARCH(AlbumTitle_Tokens, 'Blue Note') OR SEARCH(Studio_Tokens, 'Blue Note')

Sin embargo, esto tiene una semántica diferente. No coincide con los álbumes en los que AlbumTitle_Tokens tiene “azul”, pero no “nota”, y Studio_Tokens tiene “nota”, pero no “azul”.

¿Qué sigue?