En esta página, se describen la función SEARCH
y el modo de consulta mejorado, que se
usarse para realizar búsquedas en el texto completo
consultas en tablas de Spanner.
Consulta un índice de búsqueda
Spanner proporciona
SEARCH
para consultas de índice de búsqueda. La función SEARCH
requiere dos argumentos:
- Un nombre de índice de búsqueda
- Una consulta
La función SEARCH
solo funciona cuando se define un índice de búsqueda. El SEARCH
función se puede combinar con cualquier construcción SQL arbitraria, como filtros,
agregaciones o uniones.
La siguiente consulta usa la función SEARCH
para mostrar todos los álbumes que tienen
friday
o monday
en el título:
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')
El lenguaje rquery
El segundo argumento de la función SEARCH
es un lenguaje específico de dominio (DSL).
llamada rquery. El lenguaje rquery es similar al que son los usuarios de Internet
acostumbrados a usar en google.com:
- Varios términos implican
AND
. Por ejemplo, "Big Time" equivale abig AND time
. La operación
OR
implica una disyunción entre dos términos, comobig OR time
. La instrucciónSEARCH(tl, 'big time OR fast car')
es equivalente a lo siguiente:SEARCH(tl, 'big') AND (SEARCH(tl, 'time') OR SEARCH(tl, 'fast')) AND SEARCH(tl, 'cat');
OR
solo se aplica a los dos términos adyacentes. Por ejemplo, el cuadro de búsqueda la expresiónhappy friday OR monday
busca todos los documentos que tienen el términohappy
y el términofriday
omonday
.Las comillas dobles indican una búsqueda de frase. Por ejemplo, la consulta
"big cat"
coincide con "Tengo un gato grande", pero no con "Mi gato es grande".El operador
AROUND
hace coincidir los términos que se encuentran a una distancia determinada de entre sí. Por ejemplo, rquerybig AROUND cat
coincide con “grande, blanco y gato peludo”, pero no coincide con “perro grande estaba sentado junto a un gato pequeño”. La opción predeterminada es hacer coincidir los términos separados por, como máximo, cinco posiciones. Para ajusta la distancia y pasa un argumento al operadorAROUND
. Spanner admite dos sintaxis paraAROUND
:big AROUND(10) cat
big AROUND 10 cat
El operador
AROUND
, cuando se usa como parte de una frase, puede coincidir con términos que estén a cierta distancia unas de otras y en el mismo orden (las el valor predeterminado es de cinco tokens). Por ejemplo, si la cadenabig AROUND cat
coincide “gato blanco grande y peludo”, pero no “gato grande”.La negación de un solo token se expresa con un guion (
-
). Por ejemplo:-dog
coincide con todos los documentos que no contienen el términodog
.Por lo general, se ignora la puntuación. Por ejemplo, "¡Gran momento!". equivale a “Big Time”.
La búsqueda no distingue mayúsculas de minúsculas. Por ejemplo, "Big Time" coincide con “big time”.
Los operadores
The OR
yAROUND
distinguen mayúsculas de minúsculas. El carácter de barra vertical (|
) es la combinación de teclas paraOR
.
Cómo funciona el lenguaje rquery
El lenguaje rquery sigue las mismas reglas que el tokenizador de texto sin formato cuando se divide la cadena de entrada en términos distintos. Esto incluye la segmentación de los idiomas asiáticos.
Muchas aplicaciones permiten que sus usuarios ingresen una consulta de búsqueda en una
en el cuadro de búsqueda. La forma más sencilla de integrar estas consultas de los usuarios finales es enviar la
la entrada del usuario directamente en la función SEARCH
En la siguiente tabla, se explica el significado de varias cadenas de rquery:
rquery | Explicación |
---|---|
Big Cat |
Hace coincidir los documentos que contienen ambos términos "grande" y "gato". |
cat OR dog |
Hace coincidir los documentos que contienen al menos uno de los términos “gato” y "perro". |
-cat |
Coincide con todos los documentos que no contienen el término “gato”. |
"big dog" -"big cat" |
Hace coincidir los documentos que contienen dos términos adyacentes “grande” y "perro", pero que no contengan las palabras “grandes” adyacentes y "gato". Por ejemplo, esta búsqueda coincide con "Tengo un perro grande y un gato pequeño", pero no con "Tengo un perro grande y un gato grande". |
cat|dog |
Esto es igual a gato O perro. |
and OR or |
Hace coincidir los documentos que contienen el término "y" o el término "o" (el operador OR debe estar en mayúsculas) |
Modo de consulta mejorado
Además de la búsqueda de texto completo basada en tokens, Spanner
admite un modo más enriquecido llamado enhance_query
. Cuando está habilitado, este modo extiende
la búsqueda para incluir más variantes de token. Estas reescrituras
aumentan la búsqueda
recuperación.
Para habilitar esta opción, establece el argumento opcional enhance_query=>true
en el archivo
Función SEARCH
. Por ejemplo, la búsqueda hotl cal
coincide con el álbum.
Hotel California
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)
El modo enhance_query
es una opción de tiempo de consulta. No afecta la tokenización.
Puedes usar el mismo índice de búsqueda con o sin enhance_query
.
Google está mejorando continuamente los algoritmos de mejora de las búsquedas. Como
resultado, una consulta con enhance_query == true
podría generar un rendimiento ligeramente diferente
con el tiempo...
Cuando el modo enhance_query
está habilitado, es posible que aumente la cantidad de términos
que busca la función SEARCH
, que puede generar un nivel ligeramente elevado
latencia.
Por ejemplo, la siguiente consulta usa un tiempo de espera de tres segundos y falla si
enhance_query
no está disponible:
@{require_enhance_query=true, enhance_query_timeout_ms=3000}
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'cat', enhance_query=>true)
Requisitos de las consulta en SQL
Existen varias condiciones que una consulta en SQL debe cumplir para usar un índice de búsqueda. Si no se cumplen estas condiciones, la consulta usa un plan de consultas alternativo. o falla si no existe un plan alternativo.
Las consultas deben cumplir con las siguientes condiciones:
- Las funciones
SEARCH
ySEARCH_SUBSTRING
requieren un índice de búsqueda. Spanner no admite estas funciones en las consultas la tabla base o los índices secundarios. Consultas en Índices particionados debe tener todas las columnas de partición vinculadas por una condición de igualdad en la
WHERE
de la consulta.Por ejemplo, si un índice de búsqueda se define como
PARTITION BY x, y
, el valor La consulta debe tener un conjunto en la cláusulaWHERE
dex = <parameter or constant> AND y = <parameter or constant>
. Ese índice de búsqueda no es considerada por el optimizador de consultas si dicha condición no se encuentra.Todas las
TOKENLIST
columnas a las que hacen referenciaSEARCH
ySEARCH_SUBSTRING
los operadores deben estar indexados en el mismo índice de búsqueda.Por ejemplo, considera la siguiente definición de tabla y de índice:
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 siguiente consulta falla porque no hay un solo índice de búsqueda que indexe
AlbumTitle_Tokens
yAlbumStudio_Tokens
:SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)
Si la columna de orden de clasificación es anulable, tanto el esquema como la consulta deben excluir las filas en las que la columna de orden de clasificación sea NULL. Consulta Orden de clasificación del índice de búsqueda para conocer los detalles.
Si el índice de búsqueda tiene el filtro NULL, la consulta debe incluir el mismo Es la expresión de filtrado NULL que se usa en un índice. Consulta Búsqueda con filtro NULL índices para conocer los detalles.
Los índices de búsqueda no son compatibles con DML, DML particionado ni particionado las consultas .
Los índices de búsqueda suelen usarse transacciones de solo lectura. Si los requisitos de la aplicación permiten resultados inactivos, recomendamos ejecutar la búsqueda consultas con una duración de inactividad de 10 segundos o más. Para ver más información, consulta Lee datos inactivos. Este es particularmente útil para búsquedas grandes que se distribuyen a varios Paxos grupos.
No se recomiendan los índices de búsqueda en transacciones de lectura y escritura. Durante la ejecución, las consultas de búsqueda bloquean toda una partición de índice; como como resultado, una tasa alta de consultas de búsqueda en transacciones de lectura y escritura conflictos de bloqueo que provocan aumentos repentinos de latencia. De forma predeterminada, los índices de búsqueda se seleccionan automáticamente en las transacciones de lectura y escritura. Si una consulta se ve obligada a usar un índice de búsqueda en una transacción de lectura y escritura, falla de forma predeterminada. Esta el comportamiento se puede anular Sugerencia a nivel de sentencia
@{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE}
(pero todavía pueden causar conflictos de bloqueo).
Una vez que se cumplen las condiciones de elegibilidad de los índices, el optimizador de consultas intenta
acelerar las condiciones de consultas que no son de texto (como Rating > 4
). Si el índice de búsqueda
no incluye la columna TOKENLIST
adecuada, la condición no
se acelera y sigue siendo una condición residual.
Parámetros de consulta
rquery y otros parámetros, como OFFSET
, se especifican como un literal o un parámetro de consulta.
Recomendamos usar parámetros de consulta en lugar de literales de cadena. Parametrizado
las consultas tienen mejor consulta
de aciertos de caché, lo que da como resultado
menor latencia de consulta y menor uso general de la CPU.
Por ejemplo, en lugar de usar una consulta como la siguiente:
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'cat')
usa la siguiente sintaxis:
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, @p)
Spanner ejecuta el optimizador de consultas en textos de SQL distintos. Menos textos de SQL distintos utiliza la aplicación, menos veces que la consulta se invoca la optimización.
Orden de clasificación del índice de búsqueda
El comportamiento del orden de clasificación de los índices de búsqueda es diferente del comportamiento de los secundarios índices.
Por ejemplo, considera la siguiente tabla:
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
ReleaseTimestamp INT64 NOT NULL,
AlbumName STRING(MAX),
AlbumName_Token TOKENLIST AS (TOKEN(AlbumName)) HIDDEN
) PRIMARY KEY(AlbumId);
La aplicación puede definir un índice secundario para buscar información con el
AlbumName
ordenadas por ReleaseTimestamp
:
CREATE INDEX AlbumsSecondaryIndex ON Albums(AlbumName, ReleaseTimestamp DESC);
El índice de búsqueda equivalente se ve de la siguiente manera (esto utiliza la concordancia exacta la asignación de token, ya que los índices secundarios no admiten búsquedas en el texto completo):
CREATE SEARCH INDEX AlbumsSearchIndex
ON Albums(AlbumName_Token)
ORDER BY ReleaseTimestamp DESC;
El orden de clasificación del índice de búsqueda debe cumplir con las siguientes reglas:
- Usar solo columnas
INT64
para ordenar de un índice de búsqueda. Las columnas con tamaños arbitrarios utilizan demasiados recursos en el índice de búsqueda porque Spanner necesita almacenar el docid al lado de cada token. Específicamente, la columna de orden no puede usar el tipoTIMESTAMP
porqueTIMESTAMP
usa precisión de nanosegundos, que no se ajusta a un número entero de 64 bits. Las columnas de orden de clasificación no deben ser
NULL
. Existen dos maneras de cumplir con esto requisito:- Declara la columna de orden de clasificación como
NOT NULL
. - Configura el índice para excluir los valores NULL.
- Declara la columna de orden de clasificación como
En la práctica, se suele usar una marca de tiempo para determinar el orden de clasificación. Un problema común práctica es usar microsegundos ya que el epoch para esas marcas de tiempo.
Las aplicaciones generalmente recuperan los datos más recientes primero mediante un índice de búsqueda que en orden descendente.
Selección de índices
Spanner suele seleccionar el índice más eficiente para una consulta
con el modelado basado en costos. Sin embargo, la sugerencia FORCE_INDEX
indica de forma explícita
Spanner para usar un índice de búsqueda específico Por ejemplo, el
A continuación, se muestra cómo forzar a Spanner a usar AlbumsIndex
:
SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, @p1)
Si el índice de búsqueda especificado no es apto, el la consulta falla, incluso si hay otros índices de búsqueda aptos.
Fragmentos en los resultados de la búsqueda
Un fragmento es un fragmento de texto extraído de una cadena determinada que ofrece a los usuarios una idea de lo que contiene un resultado de la búsqueda y el motivo por el cual relevantes para su consulta.
Por ejemplo, Gmail utiliza fragmentos para indicar la parte de un correo electrónico que coincide con la búsqueda:
Hacer que la base de datos genere un fragmento tiene varios beneficios:
- Comodidad: No es necesario que implementes la lógica para generar fragmentos. de una búsqueda.
- Eficiencia: Los fragmentos reducen el tamaño de los resultados del servidor.
La función SNIPPET
crea el fragmento. Devuelve la parte relevante de
el valor original de la cadena junto con las posiciones de los caracteres que se deben destacar. Luego, el cliente puede elegir cómo mostrar el fragmento al usuario final (por ejemplo, con texto destacado o en negrita). La función SNIPPET
quita todas las etiquetas HTML.
de la cadena original.
Por ejemplo, lo siguiente usa SNIPPET
para recuperar texto de AlbumTitle
:
SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")
¿Qué sigue?
- Obtenga información sobre cómo clasificar los resultados de la búsqueda.
- Obtén información para realizar una búsqueda de substring.
- Obtén información sobre cómo paginar los resultados de la búsqueda.
- Obtén más información sobre cómo combinar consultas de texto completo y no de texto.
- Obtén más información sobre cómo buscar en varias columnas.