Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Información general de la búsqueda vectorial
La búsqueda vectorial está basada en la creación, el mantenimiento y el uso de índices. Cada operación de búsqueda vectorial especifica un índice único y su operación se limita a ese índice, es decir, las operaciones de un índice no afectan las operaciones de ningún otro índice. A excepción de las operaciones de creación y destrucción de índices, se puede realizar cualquier cantidad de operaciones en cualquier índice en cualquier momento, lo que significa que, a nivel de clúster, pueden estar en ejecución varias operaciones en varios índices simultáneamente.
Los índices individuales son objetos con nombre que existen en un espacio de nombres único, que está separado de los demás espacios de nombres de Valkey y OSS Redis: claves, funciones, etc. Cada índice es conceptualmente similar a una tabla de base de datos convencional, dada su estructura en dos dimensiones: columnas y filas. Cada fila de la tabla corresponde a una clave. Cada columna del índice corresponde a un miembro o a una parte de esa clave. En este documento, los términos clave, fila y registro son idénticos y se usan indistintamente. Del mismo modo, los términos columna, campo, ruta y miembro son idénticos en esencia y también se usan indistintamente.
No existen comandos especiales para añadir, eliminar o modificar los datos indexados. Por el contrario, los comandos HASH o JSON existentes que modifican una clave que está en un índice también lo actualizan automáticamente.
Temas
Los índices y el espacio de claves de Valkey y Redis OSS
Los índices se construyen y mantienen en un subconjunto del espacio de claves de Valkey y Redis. OSS Los índices múltiples pueden elegir subconjuntos disjuntos o superpuestos del espacio de claves sin limitación alguna. Durante la creación del índice se proporciona una lista de prefijos clave que definen el espacio de claves de cada índice. La lista de prefijos es opcional y, si se omite, todo el espacio de claves formará parte de ese índice. Los índices también están tipificados en el sentido de que solo incluyen las claves de tipo coincidente. Por el momento, solo se admiten los HASH índices JSON y los índices. Un HASH índice solo indexa HASH las claves incluidas en su lista de prefijos y, de manera similar, un JSON índice solo indexa JSON las claves incluidas en su lista de prefijos. Las claves incluidas en la lista de prefijos del espacio de claves de un índice que no poseen el tipo designado se ignoran y no afectan a las operaciones de búsqueda.
Cuando un JSON comando HASH or modifica una clave que se encuentra dentro del espacio de claves de un índice, ese índice se actualiza. Este proceso implica la extracción de los campos declarados para cada índice y la actualización del índice con el nuevo valor. El proceso de actualización ocurre en un subproceso en segundo plano, lo que significa que en última instancia los índices solo son coherentes con el contenido de su espacio de claves. Por lo tanto, la inserción o actualización de una clave no será visible en los resultados de búsqueda durante un breve período de tiempo. Durante los períodos en los que el sistema está sobrecargado o hay grandes cambios en los datos, el retraso en la visibilidad puede prolongarse.
La creación de un índice es un proceso de varios pasos. El primer paso es ejecutar el FT. CREATEcomando que define el índice. Al ejecutarse correctamente el comando create, se inicia automáticamente el segundo paso: la reposición. El proceso de relleno se ejecuta en un subproceso en segundo plano y escanea el espacio clave en busca de claves que estén dentro de la lista de prefijos del nuevo índice. Cada clave que se encuentra se agrega al índice. Finalmente, se analiza todo el espacio de claves y se completa el proceso de creación del índice. Tenga en cuenta que mientras el proceso de reposición está en marcha, se permiten las mutaciones de las claves indexadas, no hay restricciones y el proceso de reposición del índice no finalizará hasta que todas las claves estén indexadas correctamente. No se permiten las operaciones de consulta realizadas mientras se está rellenando un índice y se las finaliza con un error. La finalización del proceso de reposición se puede determinar a partir del resultado del comando FT.INFO
para ese índice ('backfill_status').
El campo de índice escribe
Cada campo (columna) de un índice tiene un tipo específico que se declara durante la creación del índice y una ubicación dentro de una clave. En el caso de HASH las claves, la ubicación es el nombre del campo dentro de. HASH En el JSON caso de las claves, la ubicación es la descripción de una JSON ruta. Al modificar una clave, los datos asociados a los campos declarados se extraen, se convierten al tipo declarado y se almacenan en el índice. Si faltan los datos o no se pueden convertir correctamente al tipo declarado, ese campo se omite del índice. Hay cuatro tipos de campos, según se explica a continuación:
Los campos numéricos contienen un solo número. En el caso de JSON los campos, se deben seguir las reglas numéricas de JSON los números. Para HASH ello, se espera que el campo contenga el ASCII texto de un número escrito en el formato estándar para números de coma fija o flotante. Independientemente de la representación que contenga la clave, este campo se convierte en un número de punto flotante de 64 bits para almacenarlo en el índice. Los campos numéricos se pueden utilizar con el operador de búsqueda por rangos. Como los números subyacentes se almacenan en punto flotante con sus limitaciones de precisión, se aplican las reglas habituales sobre las comparaciones numéricas de números de punto flotante.
Los campos de etiquetas contienen cero o más valores de etiqueta codificados como una sola cadena de UTF -8. La cadena se analiza en valores de etiqueta mediante un carácter separador (el valor predeterminado es una coma, pero se puede anular) y se eliminan los espacios en blanco iniciales y finales. Se puede incluir cualquier número de valores de etiqueta en un único campo de etiqueta. Los campos de etiquetas se pueden usar para filtrar las consultas y determinar la equivalencia de los valores de las etiquetas mediante una comparación que distinga entre mayúsculas y minúsculas o que no distinga entre mayúsculas y minúsculas.
Los campos de texto contienen un bloque de bytes que no es necesario que sean compatibles con UTF -8. Los campos de texto se pueden usar para decorar los resultados de las consultas con valores significativos para la aplicación. Por ejemplo, a URL o el contenido de un documento, etc.
Los campos vectoriales contienen un vector de números, también conocido como una incrustación. Los campos vectoriales admiten la búsqueda de K vecinos más cercanos (KNN) de vectores de tamaño fijo mediante un algoritmo y una métrica de distancia específicos. En el caso de HASH los índices, el campo debe contener todo el vector codificado en formato binario (IEEElittle-endian 754). En el caso de JSON las claves, la ruta debe hacer referencia a una matriz del tamaño correcto llena de números. Tenga en cuenta que cuando se utiliza una JSON matriz como campo vectorial, la representación interna de la matriz dentro de la JSON clave se convierte al formato requerido por el algoritmo seleccionado, lo que reduce el consumo de memoria y la precisión. Las operaciones de lectura posteriores mediante los JSON comandos producirán un valor de precisión reducido.
Algoritmos de índice vectorial
Se proporcionan dos algoritmos de índice vectorial:
FLAT: el algoritmo Flat es un procesamiento lineal de fuerza bruta de cada vector del índice, que da como resultado respuestas exactas dentro de los límites de la precisión de los cálculos de distancia. Debido al procesamiento lineal del índice, los tiempos de ejecución de este algoritmo pueden ser muy altos para índices grandes.
HNSW(Mundos pequeños navegables jerárquicos): el HNSW algoritmo es una alternativa que proporciona una aproximación de la respuesta correcta a cambio de unos tiempos de ejecución considerablemente más bajos. El algoritmo está controlado por tres parámetros,
M
EF_CONSTRUCTION
yEF_RUNTIME
. Los dos primeros parámetros se especifican en el momento de la creación del índice y no se pueden cambiar. El parámetroEF_RUNTIME
tiene un valor predeterminado que se especifica al crear el índice, pero se puede anular posteriormente en cualquier operación de consulta individual. Estos tres parámetros interactúan para equilibrar la memoria y el CPU consumo durante las operaciones de ingesta y consulta, así como para controlar la calidad de la aproximación de una KNN búsqueda exacta (lo que se conoce como ratio de recuperación).
Ambos algoritmos de búsqueda vectorial (Flat y FlatHNSW) admiten un parámetro opcionalINITIAL_CAP
. Si se especifica, este parámetro asigna previamente memoria a los índices, lo que da como resultado una reducción de la sobrecarga de administración de la memoria y aumenta las tasas de incorporación vectorial.
HNSWEs posible que los algoritmos de búsqueda vectorial no gestionen de manera eficiente la eliminación o la sobrescritura de los vectores previamente insertados. El uso de estas operaciones puede provocar una and/or degraded recall quality. Reindexing is one method for restoring optimal memory usage and/or recuperación excesiva del consumo de memoria del índice.
Expresión de consulta de búsqueda vectorial
El FT. SEARCHy FT. AGGREGATElos comandos requieren una expresión de consulta. que es un parámetro de cadena única que se compone de uno o varios operadores. Cada operador utiliza un campo del índice para identificar un subconjunto de las claves del índice. Se pueden combinar varios operadores mediante combinadores booleanos y paréntesis para mejorar o restringir aún más el conjunto de claves (o conjunto de resultados) recopilado.
Comodín
El operador comodín, el asterisco ('*'), coincide con todas las claves del índice.
Rango numérico
El operador de rango numérico tiene la siguiente sintaxis:
<range-search> ::= '@' <numeric-field-name> ':' '[' <bound> <bound> ']' <bound> ::= <number> | '(' <number> <number> ::= <integer> | <fixed-point> | <floating-point> | 'Inf' | '-Inf' | '+Inf'
El campo < numeric-field-name > debe ser un campo de tipo declaradoNUMERIC
. De forma predeterminada, el límite es inclusivo, pero se puede usar un paréntesis abierto inicial ['('] para hacer que un límite sea exclusivo. La búsqueda por rangos se puede convertir en una comparación relacional (<, <=, > > =) única mediante Inf
, +Inf
o -Inf
como uno de los límites. Independientemente del formato numérico especificado (entero, punto fijo, punto flotante, infinito), el número se convierte en punto flotante de 64 bits para realizar comparaciones y, en consecuencia, reducir la precisión.
ejemplo Ejemplos
@numeric-field:[0 10] // 0 <= <value> <= 10 @numeric-field:[(0 10] // 0 < <value> <= 10 @numeric-field:[0 (10] // 0 <= <value> < 10 @numeric-field:[(0 (10] // 0 < <value> < 10 @numeric-field:[1.5 (Inf] // 1.5 <= value
Comparación de etiquetas
El operador de comparación de etiquetas tiene la siguiente sintaxis:
<tag-search> ::= '@' <tag-field-name> ':' '{' <tag> [ '|' <tag> ]* '}'
Si alguna de las etiquetas del operador coincide con alguna de las etiquetas del campo de etiquetas del registro, este se incluye en el conjunto de resultados. El campo diseñado por el <tag-field-name>
debe ser un campo del índice declarado con el tipo TAG
. Algunos ejemplos de una comparación de etiquetas son los siguientes:
@tag-field:{ atag } @tag-field: { tag1 | tag2 }
Combinaciones booleanas
Los conjuntos de resultados de un operador numérico o de etiquetas se pueden combinar mediante la lógica booleana: and/or. Parentheses can be used to group operators and/or cambie el orden de evaluación. La sintaxis de los operadores lógicos booleanos es la siguiente:
<expression> ::= <phrase> | <phrase> '|' <expression> | '(' <expression> ')' <phrase> ::= <term> | <term> <phrase> <term> ::= <range-search> | <tag-search> | '*'
Los términos múltiples combinados en una frase son anexados con “y”. Las frases múltiples combinadas con la barra vertical ('|') se relacionan con “o”.
Búsqueda vectorial
Los índices vectoriales admiten dos métodos de búsqueda diferentes: el vecino más cercano y el rango. La búsqueda del vecino más cercano localiza un número, K, de los vectores del índice que están más cerca del vector proporcionado (de referencia); esto se denomina coloquialmente KNN para los «K» vecinos más cercanos. La sintaxis de una KNN búsqueda es la siguiente:
<vector-knn-search> ::= <expression> '=>[KNN' <k> '@' <vector-field-name> '$' <parameter-name> <modifiers> ']' <modifiers> ::= [ 'EF_RUNTIME' <integer> ] [ 'AS' <distance-field-name>]
La KNN búsqueda vectorial solo se aplica a los vectores que cumplen los requisitos, <expression>
que pueden ser cualquier combinación de los operadores definidos anteriormente: comodín, búsqueda por rango, búsqueda por etiquetas y/o combinaciones booleanas de los mismos.
<k>
es un número entero que especifica el número de vectores vecinos más cercanos que se van a devolver.<vector-field-name>
debe especificar un campo de tipoVECTOR
declarado.El campo
<parameter-name>
especifica una de las entradas de la tablaPARAM
del comandoFT.SEARCH
oFT.AGGREGATE
. Este parámetro es el valor vectorial de referencia para los cálculos de distancia. El valor del vector se codifica en elPARAM
valor en formato binario little-endian IEEE 754 (con la misma codificación que para un campo vectorial) HASHPara los índices vectoriales de tipoHNSW, la
EF_RUNTIME
cláusula opcional se puede utilizar para anular el valor predeterminado delEF_RUNTIME
parámetro que se estableció cuando se creó el índice.La
<distance-field-name>
opcional proporciona un nombre de campo para que el conjunto de resultados contenga la distancia calculada entre el vector de referencia y la clave ubicada.
Una búsqueda por rango localiza todos los vectores dentro de una distancia (radio) especificada con respecto a un vector de referencia. La sintaxis de una búsqueda por rango es:
<vector-range-search> ::= ‘@’ <vector-field-name> ‘:’ ‘[’ ‘VECTOR_RANGE’ ( <radius> | ‘$’ <radius-parameter> ) $<reference-vector-parameter> ‘]’ [ ‘=’ ‘>’ ‘{’ <modifiers> ‘}’ ] <modifiers> ::= <modifier> | <modifiers>, <modifier> <modifer> ::= [ ‘$yield_distance_as’ ‘:’ <distance-field-name> ] [ ‘$epsilon’ ‘:’ <epsilon-value> ]
Donde:
<vector-field-name>
es el nombre del campo vectorial que se va a buscar.<radius> or $<radius-parameter>
es el límite de distancia numérico para la búsqueda.$<reference-vector-parameter>
es el nombre del parámetro que contiene el vector de referencia. El valor del vector se codifica en el PARAM valor en formato binario little-endian IEEE 754 (la misma codificación que para un HASH campo vectorial)La opción
<distance-field-name>
proporciona un nombre de campo para que el conjunto de resultados contenga la distancia calculada entre el vector de referencia y cada clave.La opción
<epsilon-value>
controla el límite de la operación de búsqueda; los vectores situados dentro de la distancia<radius> * (1.0 + <epsilon-value>)
se recorren en busca de resultados candidatos. El valor por defecto es .01.
INFOcomando
La búsqueda vectorial amplía los OSS INFOSEARCH
, se recuperarán todas las secciones siguientes:
Sección de search_memory
Nombre | Descripción |
---|---|
search_used_memory_bytes | Número de bytes de memoria consumidos en todas las estructuras de datos de búsqueda |
search_used_memory_human | Versión legible por seres humanos de lo anterior |
Sección de search_index_stats
Nombre | Descripción |
---|---|
search_number_of_indexes | Número de índices creados |
search_num_fulltext_indexes | Número de campos no vectoriales en todos los índices |
search_num_vector_indexes | Número de campos vectoriales en todos los índices |
search_num_hash_indexes | Número de índices en las teclas de texto HASH |
search_num_json_indexes | Número de índices en las claves de texto JSON |
search_total_indexed_keys | Número total de claves en todos los índices |
search_total_indexed_vectors | Número total de vectores en todos los índices |
search_total_indexed_hash_keys | Número total de claves de tipo HASH en todos los índices |
search_total_indexed_json_keys | Número total de claves de tipo en todos los índices JSON |
search_total_index_size | Bytes utilizados por todos los índices |
search_total_fulltext_index_size | Bytes utilizados por estructuras de índices no vectoriales |
search_total_vector_index_size | Bytes utilizados por estructuras de índices vectoriales |
search_max_index_lag_ms | Retraso de incorporación durante la última actualización del lote de incorporación |
Sección de search_ingestion
Nombre | Descripción |
---|---|
search_background_indexing_status | Estado de la incorporación. NO_ACTIVITY significa inactivo. Otros valores indican que hay claves en proceso de incorporación. |
search_ingestion_paused | A menos que se reinicie, siempre debe ser “no”. |
Sección de search_backfill
nota
Algunos de los campos documentados en esta sección solo están visibles cuando hay una reposición en curso.
Nombre | Descripción |
---|---|
search_num_active_backfills | Número de actividades de reposición actuales |
search_backfills_paused | Excepto cuando se agote la memoria, siempre debe ser “no”. |
search_current_backfill_progress_percentage | % de finalización (0-100) del relleno actual |
Sección de search_query
Nombre | Descripción |
---|---|
search_num_active_queries | Número de comandos FT.SEARCH y FT.AGGREGATE actualmente en curso |
Seguridad de búsqueda vectorial
ACLLos mecanismos de seguridad (listas de control de acceso)@fast
,, @read
@write
, etc.) se actualizan para incluir los nuevos comandos. @search
Los comandos de búsqueda no modifican los datos clave, lo que significa que se conserva la ACL maquinaria existente para el acceso de escritura. La presencia de HASH un índice no modifica las reglas de acceso ni las JSON operaciones; se sigue aplicando a esos comandos el control de acceso normal a nivel de clave.
También se controla el acceso de los comandos de búsqueda con un índice. ACL Las comprobaciones de acceso se realizan a nivel de índice completo, no al nivel de la clave. Esto significa que el acceso a un índice se garantiza a un usuario solo si ese usuario tiene permiso para acceder a todas las claves posibles de la lista de prefijos del espacio de claves de ese índice. En otras palabras, el contenido real de un índice no controla el acceso. Más bien, es el contenido teórico de un índice, tal como se define en la lista de prefijos, el que se utiliza para el control de seguridad. Puede ser sencillo crear una situación en la que un usuario tenga acceso de lectura o escritura a una clave, pero no tenga acceso a un índice que contenga esa clave. Tenga en cuenta que solo se requiere acceso de lectura al espacio de claves para crear o usar un índice; no se tiene en cuenta la presencia o ausencia del acceso de escritura.
Para obtener más información sobre su uso ACLs con MemoryDB, consulte Autenticación de usuarios con listas de control de acceso (). ACLs