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(可选):键值对数量乘二。
  • 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 命令执行查询。以下查询最多会返回与所提供的查询向量最相似的 5 个房源:

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

示例 2:使用混合查询进行向量搜索

在本示例中,我们将使用另外两个名为 city 和 price 的属性执行混合查询

  • 说明 - 给定房源的向量嵌入。
  • 城市 - 城市名称。
  • 价格 - 房源的费用。

首先,我们创建一个索引,将“description”作为向量字段、“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

现在,我们可以执行查询了。以下查询最多会返回与所提供的查询向量最相似的 5 个房源,并且仅过滤出价格低于 100, 000 美元的 BANGALORE 房源:

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