FT.SEARCH

FT.SEARCH 會使用提供的查詢搜尋索引,並傳回指定值。請注意,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 (選用):只傳回文件 ID,不包含內容。
  • TIMEOUT (選用):可為搜尋指令設定逾時值。
  • PARAMS (選用):鍵/值組合的數量乘以 2。
  • RETURN (選用):指定要從文件中擷取的欄位,以及傳回值的任何別名。根據預設,系統會傳回所有欄位,除非設定 NOCONTENT 選項,否則不會傳回任何欄位。如果將 num 設為 0,其行為與 NOCONTENT 相同。
  • LIMIT (選用):可讓您選擇使用偏移值和數字計數進行分頁。如未使用這個參數,系統會預設為 LIMIT 0 10,最多傳回 10 個金鑰。
  • DIALECT 2 (選用):指定方言。系統僅支援方言 2。

指令回傳

  • 這項指令會傳回陣列或錯誤訊息。傳回陣列的元素代表查詢的最佳相符結果。每個陣列元素都具有下列屬性:

  • 項目的雜湊鍵

  • 下列項目的陣列:

    • 鍵/值:[$score_as ] score_value
    • 距離值
    • 屬性名稱
    • 向量值

    如果使用 NOCONTENT,陣列元素只會包含文件 ID。

範例 1:簡單的向量搜尋查詢

以這個範例來說,假設我們要建立房地產搜尋索引,讓顧客可以根據某些特徵搜尋房地產。假設我們有一份房源清單,包含下列屬性:

  • 說明 - 指定屬性的向量嵌入。
  • 其他欄位 - 每個屬性也可以有其他中繼資料。不過,為求簡單,本範例會忽略其他欄位。

首先,我們使用 FT.CREATE 指令,以說明做為向量欄位建立 HNSW 索引:

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.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

範例 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

現在可以執行查詢。下列查詢會傳回最多五個與所提供查詢向量最相似的屬性,並只篩選出位於 BANGALORE 且價格低於 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

傳回的結果:

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.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