FT.SEARCH
recherche l'index avec la requête fournie et renvoie les valeurs spécifiées.
Pour en savoir plus sur la syntaxe des requêtes, consultez Syntaxe des requêtes.
Syntaxe
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
(obligatoire) : index que vous souhaitez interroger.query
(obligatoire) : votre requête. Pour en savoir plus sur la syntaxe des requêtes, consultez Syntaxe des requêtes.NOCONTENT
(facultatif) : renvoie uniquement les ID des documents et exclut le contenu.TIMEOUT
(facultatif) : vous permet de définir une valeur de délai avant expiration pour la commande de recherche.PARAMS
(facultatif) : nombre de paires clé/valeur multiplié par deux.RETURN
(facultatif) : spécifie les champs que vous souhaitez récupérer dans vos documents, ainsi que les alias des valeurs renvoyées. Par défaut, tous les champs sont renvoyés, sauf si l'optionNOCONTENT
est définie. Dans ce cas, aucun champ n'est renvoyé. Si num est défini sur 0, il se comporte de la même manière queNOCONTENT
.LIMIT
(facultatif) : vous permet de choisir la pagination avec un décalage et un nombre. Si vous n'utilisez pas ce paramètre, la valeur par défaut estLIMIT 0 10
, qui renvoie au maximum 10 clés.DIALECT 2
(facultatif) : spécifie votre dialecte. Le seul dialecte accepté est le dialecte 2.
Retour de commande
Cette commande renvoie un tableau ou un message d'erreur. Les éléments du tableau renvoyé représentent les résultats les plus pertinents de la requête. Chaque élément du tableau comporte les éléments suivants :
Clé de hachage de l'entrée
Tableau contenant les éléments suivants :
- Valeur clé : [$score_as ] score_value
- Valeur de la distance
- Nom de l'attribut
- Valeur du vecteur
Si
NOCONTENT
est utilisé, les éléments du tableau ne contiennent que les ID de document.
Exemple 1 : Requête de recherche vectorielle simple
Pour cet exemple, supposons que nous créons un index de recherche de propriétés dans lequel les clients peuvent rechercher des propriétés en fonction de certaines caractéristiques. Supposons que nous disposions d'une liste de propriétés avec les attributs suivants :
- Description : embedding vectoriel pour la propriété donnée.
- Autres champs : chaque propriété peut également comporter d'autres métadonnées. Toutefois, pour plus de simplicité, les autres champs sont ignorés dans cet exemple.
Nous allons d'abord créer un index HNSW avec la description comme champ vectoriel à l'aide de la commande FT.CREATE
:
FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2
Nous pouvons maintenant insérer quelques propriétés (cela peut également être fait avant la création de l'index) à l'aide de la commande 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?"
Nous pouvons maintenant effectuer des requêtes à l'aide de la commande FT.SEARCH. La requête suivante renvoie jusqu'à cinq des propriétés les plus similaires au vecteur de requête fourni :
FT.SEARCH idx "*=>[KNN 5 @description $query_vector]" PARAMS 2 query_vector "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00" DIALECT 2
Résultat renvoyé :
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
Exemple de code
Python
# Before running, ensure you have installed redis-py: # pip install redis import redis client = redis.Redis(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(6379, "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
Exemple 2 : Recherche vectorielle avec requêtes hybrides
Pour cet exemple, nous allons effectuer une requête hybride en utilisant deux attributs supplémentaires nommés "city" (ville) et "price" (prix) :
- Description : embedding vectoriel pour la propriété donnée.
- Ville : nom de la ville.
- Prix : coût de la propriété.
Tout d'abord, nous créons un index avec la description comme champ vectoriel, la ville comme champ de tag et le prix comme champ numérique :
FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2 city TAG price NUMERIC
Nous pouvons maintenant insérer quelques propriétés (cela peut également être fait avant la création de l'index) :
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
Nous pouvons maintenant exécuter des requêtes. La requête suivante renvoie jusqu'à cinq des propriétés les plus similaires au vecteur de requête fourni, en filtrant uniquement celles situées à BANGALORE et dont le prix est inférieur à 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
Résultat renvoyé :
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
Pour en savoir plus sur le format des requêtes de filtre, consultez la section Syntaxe des requêtes.
Exemple de code
Python
# Before running, ensure you have installed redis-py: # pip install redis import redis client = redis.Redis(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(6379, "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