FT.SEARCH מחפשת באינדקס את השאילתה שצוינה ומחזירה את הערכים שצוינו.
פרטים על תחביר של שאילתות זמינים במאמר תחביר של שאילתות.
תחביר
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(חובה): האינדקס שרוצים לשלוח אליו שאילתה. -
query(חובה): השאילתה. לפרטים על תחביר השאילתה, אפשר לעיין במאמר בנושא תחביר של שאילתות. -
NOCONTENT(אופציונלי): מחזיר רק את מזהי המסמכים, ולא כולל את התוכן. -
TIMEOUT(אופציונלי): מאפשר להגדיר ערך של זמן קצוב לתפוגה עבור פקודת החיפוש. -
PARAMS(אופציונלי): מספר צמדי מפתח/ערך כפול שתיים. -
RETURN(אופציונלי): מציין את השדות שרוצים לאחזר מהמסמכים, יחד עם כינויים לערכים שמוחזרים. כברירת מחדל, כל השדות מוחזרים, אלא אם האפשרותNOCONTENTמוגדרת. במקרה כזה, לא מוחזרים שדות. אם הערך של num הוא 0, הפונקציה מתנהגת כמוNOCONTENT. -
LIMIT(אופציונלי): מאפשר לבחור מספור עמודים עם היסט ומספר ספירה. אם לא משתמשים בפרמטר הזה, ברירת המחדל היאLIMIT 0 10, שמחזירה לכל היותר 10 מפתחות. -
DIALECT 2(אופציונלי): מציינים את הדיאלקט. הדיאלקט הנתמך היחיד הוא דיאלקט 2.
החזרת פקודה
הפקודה הזו מחזירה מערך או הודעת שגיאה. האלמנטים במערך המוחזר מייצגים את התוצאות הכי מתאימות לשאילתה. כל רכיב במערך כולל את הפרטים הבאים:
מפתח הגיבוב (Hash) של הרשומה
מערך של הפריטים הבאים:
- ערך מרכזי: ציון [$score_as ] score_value
- ערך המרחק
- שם המאפיין
- ערך וקטור
אם משתמשים ב-
NOCONTENT, רכיבי המערך כוללים רק את מזהי המסמכים.
דוגמה 1: שאילתת חיפוש פשוטה של וקטורים
בדוגמה הזו, נניח שאנחנו בונים אינדקס לחיפוש נכסים שבו לקוחות יכולים לחפש נכסים על סמך כמה מאפיינים. נניח שיש לנו רשימה של נכסים עם המאפיינים הבאים:
- תיאור – הטמעת וקטורים עבור נכס נתון.
- שדות אחרים – לכל נכס יכולים להיות גם מטא-נתונים אחרים. עם זאת, כדי לפשט את הדוגמה, המערכת מתעלמת משדות אחרים.
קודם כל, יוצרים אינדקס HNSW עם התיאור כשדה וקטורי באמצעות הפקודה FT.CREATE:
FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2
עכשיו אפשר להוסיף כמה מאפיינים (אפשר לעשות את זה גם לפני יצירת האינדקס) באמצעות הפקודה 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?"
עכשיו אפשר להריץ שאילתות באמצעות הפקודה FT.SEARCH. השאילתה הבאה מחזירה עד חמישה מהנכסים הכי דומים לווקטור השאילתה שצוין:
FT.SEARCH idx "*=>[KNN 5 @description $query_vector]" PARAMS 2 query_vector "\xcd\xccL?\x00\x00\x00\x00\x00\x00\x00\x00" DIALECT 2
התוצאה שהוחזרה:
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
קוד לדוגמה
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
דוגמה 2: חיפוש וקטורי עם שאילתות היברידיות
בדוגמה הזו נבצע שאילתה היברידית באמצעות שני מאפיינים נוספים בשם city (עיר) ו-price (מחיר):
- תיאור – הטמעת וקטורים עבור נכס נתון.
- עיר – שם העיר.
- מחיר – עלות הנכס.
קודם כל, יוצרים אינדקס עם התיאור כשדה וקטורי, העיר כשדה תג והמחיר כשדה מספרי:
FT.CREATE idx SCHEMA description VECTOR HNSW 6 TYPE FLOAT32 DIM 3 DISTANCE_METRIC L2 city TAG price NUMERIC
עכשיו אפשר להוסיף כמה מאפיינים (אפשר לעשות את זה גם לפני יצירת האינדקס):
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
עכשיו אפשר להריץ שאילתות. השאילתה הבאה מחזירה עד חמישה נכסים שהכי דומים לווקטור השאילתה שסופק, ומסננת רק את הנכסים בבנגלור שמחירם נמוך מ-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
התוצאה שהוחזרה:
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
פרטים על פורמט שאילתת הסינון מופיעים במאמר בנושא תחביר שאילתות.
קוד לדוגמה
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