FT.SEARCH pesquisa o índice com a consulta fornecida e retorna os valores especificados. O FT.SEARCH retorna resultados para todo o cluster, não apenas para o nó consultado.
Também é possível usar FT.SEARCH para documentos JSON. Para ativar essa funcionalidade,
crie um índice usando FT.CREATE nos
dados JSON e especifique os campos que você quer indexar.
Para detalhes sobre a sintaxe de 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): sua consulta. Para detalhes sobre a sintaxe de consulta, consulte Sintaxe de consulta.NOCONTENT(opcional): retorna apenas os IDs de documentos e exclui o 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, além de aliases para os valores retornados. Por padrão, todos os campos são retornados, a menos que a opçãoNOCONTENTesteja definida. Nesse caso, nenhum campo é retornado. Se o número for definido como 0, ele se comportará da mesma forma queNOCONTENT.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 2.
Retorno de comando
Esse comando retorna uma matriz ou uma mensagem de erro. Os elementos da matriz retornada representam os resultados mais correspondentes da consulta. Cada elemento da matriz tem o seguinte:
A chave de hash de entrada
Uma matriz do seguinte:
- Valor da chave: [$score_as ] score_value
- Valor da distância
- Nome do atributo
- Valor do vetor
Se
NOCONTENTfor usado, os elementos da matriz consistirão apenas nos IDs de documentos.
Exemplo 1: consulta de pesquisa de vetor simples
Para este exemplo, vamos criar um índice de pesquisa de propriedades em que os clientes podem pesquisar propriedades com base em alguns recursos. Vamos supor que temos uma lista de propriedades com os seguintes atributos:
- Descrição: embedding de vetor para a propriedade especificada.
- 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 realizar 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_redis_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_redis_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_redis_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 de vetor com consultas híbridas
Para este exemplo, vamos fazer uma consulta híbrida usando mais dois atributos chamados "city" e "price":
- Descrição: embedding de vetor para a propriedade especificada.
- Cidade: nome da cidade.
- Preço: custo da propriedade.
Primeiro, criamos um índice com a descrição como um campo de vetor, 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 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 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 de 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_redis_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_redis_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_redis_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