FT.SEARCH

FT.SEARCH pesquisa o índice com a consulta fornecida e retorna os valores especificados. A FT.SEARCH retorna resultados para todo o cluster, não apenas para o nó consultado.

Para detalhes sobre a sintaxe da consulta, consulte Sintaxe de consulta.

Sintaxe

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 (obrigatório): o índice que você quer consultar.
  • query (obrigatório): é a consulta. Para detalhes sobre a sintaxe da consulta, consulte Sintaxe de consulta.
  • NOCONTENT (opcional): retorna apenas os IDs dos documentos e exclui as conteúdo.
  • TIMEOUT (opcional): permite definir um valor de tempo limite para o comando de pesquisa.
  • PARAMS (opcional): o número de pares de chave-valor vezes dois.
  • RETURN (opcional): especifica os campos que você quer recuperar dos documentos, junto com os aliases dos valores retornados. Por padrão, todos os campos são retornados, a menos que a opção NOCONTENT seja definida. Nesse caso, nenhum campo é retornado. Se "num" for definido como 0, ele vai se comportar da mesma forma que NOCONTENT.
  • LIMIT (opcional): permite escolher a paginação com um deslocamento e uma contagem de números. Se você não usar esse parâmetro, o padrão será LIMIT 0 10. que retorna no máximo 10 chaves.
  • DIALECT 2 (opcional): especifica seu dialeto. O único dialeto compatível é o dialeto 2.

Retorno de comando

  • Esse comando retorna uma matriz ou uma mensagem de erro. Os elementos do matriz retornada representam os resultados com melhor correspondência da consulta. Cada elemento de matriz tem o seguinte:

  • A chave de hash de entrada

  • Uma matriz do seguinte:

    • Chave-valor: [$score_as ] score_value
    • Valor da distância
    • Nome do atributo
    • Valor do vetor

    Se NOCONTENT for usado, os elementos da matriz vão consistir apenas dos IDs dos documentos.

Exemplo 1: consulta de pesquisa de vetor simples

Neste exemplo, vamos supor que estamos criando um índice de pesquisa de propriedades em que os clientes podem pesquisar propriedades com base em alguns recursos. Suponha que temos uma lista de propriedades com os seguintes atributos:

  • Descrição: embedding de vetor para uma determinada propriedade.
  • Outros campos: cada propriedade também pode ter outros metadados. No entanto, para simplificar, outros campos são ignorados neste exemplo.

Primeiro, criamos um índice HNSW com a descrição como um campo de vetor usando o comando FT.CREATE:

FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2

Agora podemos inserir algumas propriedades (isso também pode ser feito antes da criação do índice) usando o 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?"

Agora podemos executar consultas usando o comando FT.SEARCH. A consulta a seguir retorna até cinco das propriedades mais semelhantes ao vetor de consulta fornecido:

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 retornado:

 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

Exemplo 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

Exemplo 2: pesquisa vetorial com consultas híbridas

Neste exemplo, vamos fazer uma consulta híbrida usando dois atributos adicionais chamados cidade e preço:

  • Descrição: embedding de vetor para uma determinada propriedade.
  • Cidade: nome da cidade.
  • Preço - custo da propriedade.

Primeiro, criamos um índice com a descrição como um campo vetorial, a cidade como um campo de tag e o preço como um campo numérico:

FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2 city TAG price NUMERIC

Agora, podemos inserir algumas propriedades (isso também pode ser feito antes da criação do í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

Agora podemos realizar consultas. A consulta a seguir retorna até cinco das propriedades mais semelhantes ao vetor de consulta fornecido, filtrando apenas aquelas em BANGALORE com preço inferior a 100000:

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 retornado:

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

Consulte Sintaxe da consulta para detalhes sobre o formato da consulta de filtro.

Exemplo 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