FT.SEARCH
busca en el índice con la consulta proporcionada y muestra los valores especificados. Ten en cuenta que FT.SEARCH muestra resultados para todo el clúster, no solo para el nodo que se consulta.
Para obtener detalles sobre la sintaxis de consulta, consulta Sintaxis de consulta.
Sintaxis
FT.SEARCH index query [NOCONTENT] [TIMEOUT timeout] [PARAMS nargs name value [ name value ...]] [RETURN num field [AS alias] [ field [AS alias] ... ]] [LIMIT offset num] DIALECT 2
index
(obligatorio): Es el índice que deseas consultar.query
(obligatorio): Esta es tu consulta. Para obtener detalles sobre la sintaxis de consulta, consulta Sintaxis de consulta.NOCONTENT
(opcional): Muestra solo los IDs de los documentos y excluye el contenido.TIMEOUT
(opcional): Te permite establecer un valor de tiempo de espera para el comando de búsqueda.PARAMS
(opcional): Es la cantidad de pares clave-valor multiplicada por dos.RETURN
(opcional): Especifica los campos que deseas recuperar de tus documentos, junto con los alias de los valores que se muestran. De forma predeterminada, se muestran todos los campos, a menos que se establezca la opciónNOCONTENT
, en cuyo caso no se muestran campos. Si num se establece en 0, se comporta de la misma manera queNOCONTENT
.LIMIT
(opcional): Te permite elegir la paginación con un desplazamiento y un recuento de números. Si no usas este parámetro, el valor predeterminado esLIMIT 0 10
, que muestra como máximo 10 claves.DIALECT 2
(opcional): Especifica tu dialecto. El único dialecto compatible es el 2.
Comando de retorno
Este comando muestra un array o un mensaje de error. Los elementos del array que se muestra representan los resultados de la consulta que mejor coinciden. Cada elemento del array tiene lo siguiente:
La clave de hash de entrada
Un array de lo siguiente:
- Valor clave: [$score_as ] score_value
- Valor de distancia
- Nombre del atributo
- Valor vectorial
Si se usa
NOCONTENT
, los elementos del array consisten solo en los IDs de los documentos.
Ejemplo 1: Búsqueda vectorial simple
En este ejemplo, supongamos que estamos compilando un índice de búsqueda de propiedades en el que los clientes pueden buscar propiedades en función de algunas características. Supongamos que tenemos una lista de propiedades con los siguientes atributos:
- Descripción: incorporación de vectores para una propiedad determinada.
- Otros campos: Cada propiedad también puede tener otros metadatos. Sin embargo, para simplificar, se ignoran otros campos en este ejemplo.
En primer lugar, creamos un índice de HNSW con la descripción como un campo vectorial con el comando FT.CREATE
:
FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2
Ahora podemos insertar algunas propiedades (esto también se puede hacer antes de crear el índice) con el comando HSET:
HSET p1 description "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?" HSET p2 description "\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00" HSET p3 description "\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00" HSET p4 description "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?" HSET p5 description "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?"
Ahora podemos realizar consultas con el comando FT.SEARCH. La siguiente consulta muestra hasta cinco de las propiedades más similares al vector de consulta proporcionado:
FT.SEARCH idx "*=>[KNN 5 @description $query_vector]" PARAMS 2 query_vector "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00" DIALECT 2
Resultado que se muestra:
1) (integer) 5 2) p5 3) 1) __description_score 2) 1.6400001049 3) description 4) \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80? 4) p4 5) 1) __description_score 2) 1.6400001049 3) description 4) \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80? 6) p2 7) 1) __description_score 2) 1.6400001049 3) description 4) \x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00 8) p1 9) 1) __description_score 2) 1.6400001049 3) description 4) \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80? 10) p3 11) 1) __description_score 2) 0.0399999953806 3) description 4) \x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00
Muestra de código
Python
# Before running, ensure you have installed redis-py: # pip install redis import redis client = redis.cluster.RedisCluster(host='your_server_host', port=6379) result = client.execute_command('FT.SEARCH', 'idx', '*=>[KNN 5 @description $query_vector]', 'PARAMS', '2', 'query_vector', '"\xcd\xccL?\x00\x00\x00\x00"', 'DIALECT', '2') print(result)
NodeJS
# Before running, ensure you have installed ioredis: # npm install ioredis const Redis = require("ioredis"); const redis = new Redis.Cluster([ { port: 6379, host: "your_server_host", }, ]); redis.call("FT.SEARCH", "idx", "*=>[KNN 5 @description $query_vector]", "PARAMS", "2", "query_vector", "\xcd\xccL?\x00\x00\x00\x00\x00\x00", "DIALECT", "2").then(result => { console.log(result); redis.disconnect(); });
CLI
# Before running, ensure you have install redis-cli redis-cli -h your_server_host -p 6379 FT.SEARCH idx "(*)=>[KNN 5 @description $query_vector]" PARAMS 2 query_vector "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00" DIALECT 2
Ejemplo 2: Búsqueda de vectores con consultas híbridas
En este ejemplo, haremos una búsqueda híbrida con dos atributos adicionales llamados ciudad y precio:
- Descripción: incorporación de vectores para una propiedad determinada.
- Ciudad: Es el nombre de la ciudad.
- Precio: Es el costo de la propiedad.
En primer lugar, creamos un índice con la descripción como campo de vectores, la ciudad como campo de etiquetas y el precio como campo numérico:
FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2 city TAG price NUMERIC
Ahora, podemos insertar algunas propiedades (esto también se puede hacer antes de la creación del índice):
HSET p1 description "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?" city "NEW YORK" price 500000 HSET p2 description "\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00" city "NEW JERSEY" price 400000 HSET p3 description "\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00" city "BANGALORE" price 60000 HSET p4 description "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?" city "NEW YORK" price 600000 HSET p5 description "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?" city "BANGALORE" price 75000
Ahora, podemos realizar consultas. La siguiente consulta muestra hasta cinco de las propiedades más similares al vector de consulta proporcionado, filtrando solo aquellas que se encuentran en BANGALORE con un precio inferior a 100,000:
FT.SEARCH idx "(@city:{BANGALORE} @price:[-inf 100000])=>[KNN 5 @description $query_vector]" PARAMS 2 query_vector "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00" DIALECT 2
Resultado que se muestra:
1) (integer) 2 2) p5 3) 1) __description_score 2) 1.6400001049 3) city 4) BANGALORE 5) price 6) 75000 7) description 8) \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80? 4) p3 5) 1) __description_score 2) 0.0399999953806 3) city 4) BANGALORE 5) price 6) 60000 7) description 8) \x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00
Consulta Sintaxis de consulta para obtener detalles sobre el formato de la consulta de filtro.
Muestra de código
Python
# Before running, ensure you have installed redis-py: # pip install redis import redis client = redis.cluster.RedisCluster(host='your_server_host', port=6379) result = client.execute_command('FT.SEARCH', 'idx', '(@city:{BANGALORE} @price:[-inf 100000])=>[KNN 5 @description $query_vector]', 'PARAMS', '2', 'query_vector', '"\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00"', 'DIALECT', '2') print(result)
NodeJS
# Before running, ensure you have installed ioredis: # npm install ioredis const Redis = require("ioredis"); const redis = new Redis.Cluster([ { port: 6379, host: "your_server_host", }, ]); redis.call("FT.SEARCH", "idx", "(@city:{BANGALORE} @price:[-inf 100000])=>[KNN 5 @description $query_vector]", "PARAMS", "2", "query_vector", "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00", "DIALECT", "2").then(result => { console.log(result); redis.disconnect(); });
CLI
# Before running, ensure you have install redis-cli redis-cli -h your_server_host -p 6379 FT.SEARCH idx "(@city:{BANGALORE} @price:[-inf 100000])=>[KNN 5 @description $query_vector]" PARAMS 2 query_vector "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00" DIALECT 2