Expansión de la búsqueda

En esta página, se describe cómo usar la mejora de consultas como parte de una búsqueda de texto completo.

Para aumentar la probabilidad de encontrar resultados pertinentes, Spanner ofrece capacidades avanzadas que expanden la consulta de búsqueda para incluir términos relacionados, sinónimos y correcciones ortográficas. Spanner proporciona las siguientes opciones para la mejora de consultas:

Consulta mejorada

Para usar la consulta mejorada, configura enhance_query=>true en la función SEARCH. Luego, Spanner expande automáticamente las consultas de búsqueda incluyendo términos y sinónimos relacionados, aplicando la derivación y realizando correcciones ortográficas. Por ejemplo, cuando se usa la consulta mejorada, la consulta de búsqueda hotl cal coincide con el álbum Hotel California.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'hotl cal', enhance_query=>true)

enhance_query es una opción de tiempo de consulta que no afecta la tokenización. Puedes usar el mismo índice de búsqueda con o sin enhance_query.

Google mejora continuamente los algoritmos de mejora de consultas. Como resultado, una consulta con enhance_query => true podría generar resultados ligeramente diferentes con el tiempo.

Cuando se usa enhance_query, es posible que aumente la latencia debido a la sobrecarga de expandir la consulta de búsqueda y ejecutar la consulta más grande resultante.

Diccionarios personalizados

Puedes usar diccionarios personalizados con la búsqueda de texto completo de Spanner para definir sinónimos para los términos de tu conjunto de datos. Esto es útil para capturar sinónimos, acrónimos, términos equivalentes y otras variaciones de palabras para mejorar la recuperación de los resultados de la búsqueda.

Crea una tabla de diccionario personalizado

Un diccionario personalizado es una tabla creada por el usuario que contiene pares clave-valor de términos y sus sinónimos. Para crear uno, incluye la opción fulltext_dictionary_table = true en la instrucción CREATE TABLE. La tabla debe tener dos columnas:

  • Key: Una columna de cadena no anulable para el término que se expandirá con sinónimos.
  • Value: Un array no anulable de columnas de cadenas para un array de sinónimos de la clave.

No puede haber ninguna columna que no sea Key y Value en la tabla. Si un término de búsqueda coincide con una Key en el diccionario, la búsqueda se expande para incluir todos los sinónimos correspondientes en Value junto con el término clave. En el siguiente ejemplo, se crea una tabla de diccionario personalizado llamada MyCustomDictionary. También debes configurar la opción de tabla fulltext_dictionary_table=true en esta tabla durante la creación.

GoogleSQL

CREATE TABLE MyCustomDictionary (
  Key STRING(MAX) NOT NULL,
  Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (fulltext_dictionary_table = true);

PostgreSQL

CREATE TABLE mycustomdictionary (
  key character varying  NOT NULL,
  value character varying [] NOT NULL,
  PRIMARY KEY(key)
)  WITH ( type = 'fulltext_dictionary')

Después de crear la tabla, inserta tus sinónimos:

GoogleSQL

INSERT INTO MyCustomDictionary (Key, Value) VALUES
('album', ['vinyl', 'cassette']),
('edm', ['electronic dance music']);

PostgreSQL

INSERT INTO mycustomdictionary (key, value) VALUES
('album', ARRAY['vinyl', 'cassette']),
('edm', ARRAY['electronic dance music']);

Cuando propagues la tabla, ten en cuenta lo siguiente:

  • Las claves deben ser palabras únicas.
  • Los valores pueden ser palabras únicas o frases de varias palabras. Si un valor contiene varias palabras, se trata como una búsqueda de frase durante la búsqueda expandida.
  • Todas las claves y los valores deben estar en minúsculas. Esto garantiza que coincidan con los tokens de búsqueda, que el tokenizador predeterminado convierte a minúsculas.

La expansión de la búsqueda solo se produce cuando un término de búsqueda coincide con una Key. Si un término de búsqueda coincide con un sinónimo en Value, pero no con una Key, la búsqueda no se expande. Si necesitas una asignación bidireccional (por ejemplo, para que la búsqueda de vinyl o cassette también encuentre album), también debes insertar asignaciones inversas en la tabla de diccionario. En el siguiente ejemplo, se muestra cómo insertar asignaciones bidireccionales para album, vinyl y cassette:

GoogleSQL

INSERT INTO MyCustomDictionary (Key, Value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ['album']
FROM UNNEST(['vinyl', 'cassette']) AS syn;

PostgreSQL

INSERT INTO mycustomdictionary (key, value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ARRAY['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ARRAY['album']
FROM unnest(ARRAY['vinyl', 'cassette']) AS syn;

Usa un diccionario personalizado en las consultas de búsqueda

Para usar un diccionario personalizado, especifica el nombre de la tabla de diccionario en el argumento dictionary de la función SEARCH.

  • Si un término de búsqueda es una clave en el diccionario, SEARCH también busca sus valores. El término album coincide con los mensajes que contienen vinyl o cassette.

    GoogleSQL

    SELECT MessageId, Body
    FROM Messages
    WHERE SEARCH(Body_Tokens, 'album', dictionary=>'MyCustomDictionary');
    

    PostgreSQL

    SELECT messageid, body
    FROM messages
    WHERE spanner.search(body_tokens, 'album', dictionary=>'mycustomdictionary');
    
  • Cuando un valor de diccionario contiene varias palabras, como electronic dance music para la clave edm, se trata como una búsqueda de frase. Esto significa que los términos deben aparecer de forma adyacente y en el orden exacto especificado para que se consideren una coincidencia. Por ejemplo, la siguiente consulta muestra resultados que contienen la frase exacta "electronic dance music", pero no coincide con "dance electronic music". Esto es principalmente útil para expandir acrónimos y se puede usar de la siguiente manera:

    GoogleSQL

    SELECT MessageId, Body
    FROM Messages
    WHERE SEARCH(Body_Tokens, 'edm', dictionary=>'MyCustomDictionary');
    

    PostgreSQL

    SELECT messageid, body
    FROM messages
    WHERE spanner.search(body_tokens, 'edm', dictionary=>'mycustomdictionary');
    

Inactividad de la búsqueda de diccionario

De forma predeterminada, las entradas de diccionario personalizadas se leen con una inactividad máxima de 15 segundos. Esto reduce la sobrecarga de la operación de lectura, ya que leer datos con cierta inactividad es más eficiente que leer los datos más actuales. En consecuencia, los cambios en las entradas de diccionario pueden tardar hasta 15 segundos en reflejarse en las consultas de búsqueda. Puedes anular este comportamiento de las siguientes maneras:

  • Usa la opción de tabla fulltext_dictionary_staleness.
  • Usa la sugerencia de consulta fulltext_dictionary_staleness para obtener un control más detallado.

La sugerencia de consulta anula la opción de tabla si se usan ambas.

Opción de tabla fulltext_dictionary_staleness

Puedes configurar la opción fulltext_dictionary_staleness para la tabla de diccionario. Todas las consultas que usan esta tabla de diccionario usan este valor de inactividad, a menos que la sugerencia de consulta lo anule.

GoogleSQL

En el siguiente ejemplo, se muestra cómo CREATE una tabla con la opción fulltext_dictionary_staleness:

CREATE TABLE MyCustomDictionary (
  Key STRING(MAX) NOT NULL,
  Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (
  fulltext_dictionary_table = true,
  fulltext_dictionary_staleness = '5s'
);

En el siguiente ejemplo, se muestra cómo ALTER la tabla para cambiar o configurar la opción fulltext_dictionary_staleness:

ALTER TABLE MyCustomDictionary SET OPTIONS (
  fulltext_dictionary_staleness = '60s'
);

PostgreSQL

En el siguiente ejemplo, se muestra cómo CREATE una tabla con la opción fulltext_dictionary_staleness:

-- Create with 5s staleness
CREATE TABLE mycustomdictionary (
  key character varying NOT NULL,
  value character varying[]  NOT NULL,
  PRIMARY KEY(key)
) WITH (
  type = 'fulltext_dictionary',
  fulltext_dictionary_staleness = '5s'
);

La interfaz de PostgreSQL no admite la tabla ALTER para cambiar o configurar la opción fulltext_dictionary_staleness.

Sugerencia de consulta fulltext_dictionary_staleness

Para obtener un control más detallado, puedes usar la sugerencia de consulta fulltext_dictionary_staleness para especificar una inactividad diferente para una consulta individual. Esta sugerencia anula la configuración a nivel de la tabla.

En el siguiente ejemplo, se usa una sugerencia para realizar búsquedas en la tabla de diccionario con inactividad cero. Esto garantiza que se lean las entradas de diccionario más actuales. Este enfoque puede aumentar la latencia de las consultas, ya que leer los datos más actuales es menos eficiente que permitir cierta inactividad.

GoogleSQL

@{fulltext_dictionary_staleness="0s"}
SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'Bill', dictionary=>'MyCustomDictionary');

PostgreSQL

/*@ fulltext_dictionary_staleness='0s' */
SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'Bill', dictionary=>'mycustomdictionary');

Limitaciones conocidas con las tablas de diccionario personalizadas

  • Hay compatibilidad limitada para usar la importación y exportación de Spanner con tablas de diccionario personalizadas.
  • Las tablas de diccionario personalizadas se deben crear en el esquema predeterminado y no se pueden crear en esquemas con nombre.
  • Las tablas de diccionario personalizadas solo admiten el dialecto de consulta SEARCH predeterminado.

Combinación de diccionarios personalizados con consultas mejoradas

Puedes combinar sinónimos de diccionario personalizados con enhanced query configurando dictionary y enhance_query=>true en la función SEARCH. La mejora de consultas puede expandir las consultas con sinónimos comunes o correcciones ortográficas, mientras que los diccionarios personalizados te permiten definir tus propias expansiones. Por ejemplo, si enhance_query expande album para incluir record, y MyCustomDictionary asigna album a ['vinyl', 'cassette'], la siguiente consulta coincide con los mensajes que contienen album, record, vinyl o cassette:

GoogleSQL

SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'album', enhance_query=>true, dictionary=>'MyCustomDictionary');

PostgreSQL

SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'album', enhance_query=>true, dictionary=>'mycustomdictionary');

Cuando ambas mejoras están habilitadas, operan de forma independiente en los términos de búsqueda originales, y los términos generados por una mejora no se usan como entrada para la otra.

¿Qué sigue?