TairVector是Tair自研的扩展数据结构,提供高性能、实时,集存储、检索于一体的向量数据库服务。

TairVector简介

TairVector采用多层Hash的数据结构,如下所示:TairVector数据结构TairVector提供了HNSW(Hierarchical Navigable Small World)和暴力搜索(Flat Search)两种索引算法:
  • HNSW:以图结构构建向量检索的索引,在保证较高查询精度的同时,也可以均衡实时更新的性能表现。
  • 暴力搜索:具有100%查询精度,插入数据速度快,适用于小规模数据集。
同时,TairVector支持欧式距离(Euclidean distance)、向量内积(Internal product)和Jaccard距离(Jaccard distance)等多种距离函数。相对于传统的向量检索服务,TairVector的优势为:
  • 所有数据均在内存中,支持实时更新索引,具有更短的读写时延。
  • 优化内存数据结构,占用空间更小。
  • 开箱即用,以云服务的方式整体申请即可使用,整体架构简单高效,没有复杂组件依赖。
发布记录
  1. 2022年10月13日随Tair内存型(兼容Redis 6.0)首次发布TairVector。
  2. 2022年11月22日发布6.2.2.0版本,新增支持Jaccard距离函数、TVS.GETINDEX命令支持统计每个索引的内存占用(index_data_sizeattribute_data_size)。
  3. 2022年12月26日发布6.2.3.0版本,支持集群代理模式,新增FLOAT16的向量数据类型,新增TVS.MINDEXKNNSEARCHTVS.MINDEXMKNNSEARCH命令。

最佳实践

前提条件

实例为Tair内存型(兼容Redis 6.0)。
说明 内存型(兼容Redis 5.0)实例暂不支持升级至内存型(兼容Redis 6.0),如需使用请新建内存型(兼容Redis 6.0)实例。

注意事项

  • 操作对象为Tair实例中的TairVector数据。
  • TairVector暂不支持TTL(Time To Live)、EXPIREMOVE等特性。

命令列表

表 1. TairVector命令
类型命令语法说明
索引元数据操作TVS.CREATEINDEXTVS.CREATEINDEX index_name dims algorithm distance_method [algo_param_key alog_param_value] ...

创建一个向量索引空间,同时指定构建索引和查询的具体算法,以及距离函数。该对象仅能通过TVS.DELINDEX命令删除。

TVS.GETINDEXTVS.GETINDEX index_name

查询指定的向量索引,获取该向量索引的元数据信息。

TVS.DELINDEXTVS.DELINDEX index_name

删除指定的向量索引及该索引内的所有数据。

TVS.SCANINDEXTVS.SCANINDEX cursor [MATCH pattern] [COUNT count]

扫描Tair实例中所有符合条件的向量索引。

向量数据操作TVS.HSETTVS.HSET index_name key attribute_key attribute_value [attribute_key attribute_value] ...

往向量索引中插入数据记录(key),若该记录已存在则更新并覆盖原记录。

TVS.HGETALLTVS.HGETALL index_name key

查询指定向量索引中的key对应的所有数据记录。

TVS.HMGETTVS.HMGET index_name key attribute_key [attribute_key ...]

查询指定向量索引的key中对应的attribute_key所对应的数值。

TVS.DELTVS.DEL index_name key [key ...]

在指定向量索引中,删除指定数据记录(key)。

TVS.HDELTVS.HDEL index_name key attribute_key [attribute_key ...]

在向量索引的数据记录(key)中,删除指定的attribute_key与其数值。

TVS.SCANTVS.SCAN index_name cursor [MATCH pattern] [COUNT count]

在指定向量索引中,扫描符合条件的数据记录(key)。

向量近邻查询TVS.KNNSEARCHTVS.KNNSEARCH index_name topN vector [filter_string] [param_key param_value]

在指定向量索引中,对指定的向量(VECTOR)进行近邻查询,最多可返回topN条。

TVS.MKNNSEARCHTVS.MKNNSEARCH index_name topN vector_count vector [vector ...] [filter_string] [param_key param_value]

在指定向量索引中,批量对多条向量(VECTOR)进行近邻查询。

TVS.MINDEXKNNSEARCHTVS.MINDEXKNNSEARCH index_count index_name [index_name ...] topN vector [filter_string] [param_key param_value]

在多个向量索引中,对指定的向量(VECTOR)进行近邻查询。

TVS.MINDEXMKNNSEARCHTVS.MINDEXMKNNSEARCH index_count index_name [index_name ...] topN vector_count vector [vector ...] [filter_string] [param_key param_value]

在多个向量索引中,批量对多条向量(VECTOR)进行近邻查询。

说明 本文的命令语法定义如下:
  • 大写关键字:命令关键字。
  • 斜体:变量。
  • [options]:可选参数,不在括号中的参数为必选。
  • A|B:该组参数互斥,请进行二选一或多选一。
  • ...:前面的内容可重复。

TVS.CREATEINDEX

类别说明
语法TVS.CREATEINDEX index_name dims algorithm distance_method [algo_param_key alog_param_value] ...
时间复杂度 O(1)
命令描述

创建一个向量索引空间,同时指定构建索引和查询的具体算法,以及距离函数。该对象仅能通过TVS.DELINDEX命令删除。

选项
  • index_name:向量索引名称。
  • dims:向量维度,插入该索引的向量需具有相同的向量维度,取值范围为[1, 32768]。
  • algorithm:构建、查询索引的算法,取值如下:
    • FLAT:不单独构建索引,采用暴力搜索的方式执行查询,适合1万条以下的小规模数据集。
    • HNSW:采用HNSW图结构构建整个索引,并通过该算法进行查询,适合大规模的数据集。
  • distance_method:计算向量距离函数,取值如下:
    • L2:平方欧氏距离。
    • IP:向量内积。
    • JACCARD:Jaccard距离,且需指定向量数据类型(data_type)为BINARY

    除Jaccard距离函数外,其余距离函数的向量数据类型为FLOAT32,无需指定,且不支持修改。

  • algo_param_keyalog_param_value
    • data_type,向量数据类型,取值说明如下:
      • FLOAT32:4字节的单精度浮点数。
      • FLOAT16:2字节的半精度浮点数(IEEE 754-2008标准),可节省向量存储空间,但会损失一定的精度,FLOAT16能表示的最大数值范围为[-65519, 65519]。
      • BINARY:二进制向量,仅能包含0或1,仅支持Jaccard距离函数。
    • HNSW索引的特定参数,取值说明如下:
      • ef_construct:使用HNSW算法构建索引时,动态列表的长度。默认为100,取值范围为[1,1000],该值越大则ANN查询精度越高,同时性能开销越大。
      • M:图索引结构中,每一层的最大出边数量。默认为16,取值范围为[1,100]。该值越大则ANN查询精度越高,同时性能开销越大。
返回值
  • 执行成功:返回OK。
  • 其他情况返回相应的异常信息。
示例

命令示例:

# 创建向量存储结构:向量维度为2、索引类型为HNSW、距离函数为Jaccard、向量数据类型为BINARY。
TVS.CREATEINDEX index_name0 2 HNSW JACCARD data_type BINARY

# 创建向量存储结构:向量维度为2、索引类型为HNSW、距离函数为L2、向量数据类型为FLOAT32。
TVS.CREATEINDEX index_name1 2 HNSW L2

# 创建向量存储结构:向量维度为2、索引类型为HNSW、距离函数为IP、向量数据类型为FLOAT32。
TVS.CREATEINDEX index_name2 2 HNSW IP

# 创建向量存储结构:向量维度为2、索引类型为FLAT、距离函数为L2、向量数据类型为FLOAT32。
TVS.CREATEINDEX index_name3 2 FLAT L2

# 创建向量存储结构:向量维度为2、索引类型为FLAT、距离函数为IP、向量数据类型为FLOAT32。
TVS.CREATEINDEX index_name4 2 FLAT IP

# 创建向量存储结构:向量维度为2、索引类型为FLAT、距离函数为Jaccard、向量数据类型为BINARY。
TVS.CREATEINDEX index_name5 2 FLAT JACCARD data_type BINARY

返回示例均为如下:

OK

TVS.GETINDEX

类别说明
语法TVS.GETINDEX index_name
时间复杂度O(1)
命令描述

查询指定的向量索引,获取该向量索引的元数据信息。

选项
  • index_name:向量索引名称。
返回值
  • 执行成功:返回该向量索引的元数据信息。
  • 若指定的向量索引不存在,返回(empty array)
  • 其他情况返回相应的异常信息。
示例

请提前执行如下命令:

TVS.CREATEINDEX my_index 2 HNSW L2
TVS.HSET my_index key0 VECTOR [1,2] creation_time 1730
TVS.HSET my_index key1 VECTOR [3,4] creation_time 1740
TVS.HSET my_index key2 VECTOR [5,6] creation_time 1750

命令示例(以HNSW算法的向量索引为例):

TVS.GETINDEX my_index

返回示例:

 1) "M"                    // HNSW算法模式下,图索引结构中,每一层的最大出边数量。
 2) "16"
 3) "ef_construct"         // HNSW算法模式下,动态列表的长度。
 4) "100"
 5) "algorithm"            // 索引算法。
 6) "HNSW"
 7) "distance_method"      // 向量距离函数。
 8) "L2"
 9) "dimension"            // 向量维度。
10) "2"
11) "index_name"           // 索引名称。
12) "my_index"
13) "data_count"           // 数据量。
14) "3"
15) "data_type"            // 向量数据类型。
16) "FLOAT32"
17) "index_data_size"      // 向量数据内存占用(单位:字节)。
18) "34668544"
19) "attribute_data_size"  // 属性信息内存占用(单位:字节)。
20) "528"

TVS.DELINDEX

类别说明
语法TVS.DELINDEX index_name
时间复杂度O(N),N为该向量索引中Key的数量。
命令描述

删除指定的向量索引及该索引内的所有数据。

选项
  • index_name:向量索引名称。
返回值
  • 执行成功:删除向量索引,并返回1。
  • 若指定索引不存在,返回0。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.DELINDEX index_name0

返回示例:

 (integer) 1

TVS.SCANINDEX

类别说明
语法TVS.SCANINDEX cursor [MATCH pattern] [COUNT count]
时间复杂度O(N),N为Tair实例中向量索引数量。
命令描述

扫描Tair实例中所有符合条件的向量索引。

选项
  • cursor:指定本次扫描的游标,从0开始。
  • pattern:模式匹配。
  • count:指定本次扫描的数量,默认为10。
返回值
  • 执行成功,返回一个数组:
    • 第一个元素:下次查询的游标,若已扫描完成,则返回0。
    • 第二个元素:本次查询的向量索引( index_name)名称。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.SCANINDEX 0

返回示例:

1) "0"
2) 1) "index_name1"
   2) "index_name0"
   3) "index_name2"
   4) "index_name3"

TVS.HSET

类别说明
语法TVS.HSET index_name key attribute_key attribute_value [attribute_key attribute_value] ...
时间复杂度若本次插入、更新数据无需创建索引,则时间复杂度为O(1);否则时间复杂度为O(log(N)),N为该向量索引中Key的数量。
命令描述

往向量索引中插入数据记录(key),若该记录已存在则更新并覆盖原记录。

选项
  • index_name:向量索引名称。
  • key:该记录的主键标识,该对象可通过TVS.DEL命令删除。
  • attribute_keyattribute_value:该条记录的数值,为Key-value格式。
    • 插入向量数据:需要将attribute_key设置为VECTOR关键字(必须大写),对应的attribute_value则需要为该向量索引指定维度(dims)的向量数据字符串,例如VECTOR [1,2]。一个Key仅支持写入一个VECTOR数据,若重复写入会更新并覆盖原数据。
    • 插入其他属性:可以自定义额外属性或信息,例如create_time 1663637425(创建时间)、location Hangzhou(地点)等。
返回值
  • 执行成功:返回更新成功的记录数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.HSET index_name0 key0 VECTOR [1,2] create_time 1663637425 location Hangzhou

返回示例:

(integer) 3

TVS.HGETALL

类别说明
语法TVS.HGETALL index_name key
时间复杂度O(1)
命令描述

查询指定向量索引中的key对应的所有数据记录。

选项
  • index_name:向量索引名称。
  • key:该记录的主键标识。
返回值
  • 执行成功:返回该key的所有数据记录。
  • 若指定的向量索引或key不存在,返回(empty array)
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.HGETALL index_name0 key0

返回示例:

1) "VECTOR"
2) "[1,2]"
3) "location"
4) "Hangzhou"
5) "create_time"
6) "1663637425"

TVS.HMGET

类别说明
语法TVS.HMGET index_name key attribute_key [attribute_key ...]
时间复杂度O(1)
命令描述

查询指定向量索引的key中对应的attribute_key所对应的数值。

选项
  • index_name:向量索引名称。
  • key:该记录的主键标识。
  • attribute_key:待操作的属性Key,支持指定多个。若需查询向量数据,需传入VECTOR关键字(必须大写)。
返回值
  • 执行成功:返回attribute_key对应的数值。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.HMGET index_name0 key0 create_time location VECTOR

返回示例:

1) "1663637425"
2) "Hangzhou"
3) "[1,2]"

TVS.DEL

类别说明
语法TVS.DEL index_name key [key ...]
时间复杂度O(1)
命令描述

在指定向量索引中,删除指定数据记录(key)。

选项
  • index_name:向量索引名称。
  • key:该记录的主键标识,支持指定多个。
返回值
  • 执行成功:删除指定数据记录(key),并返回删除key的数量。
  • 若指定索引不存在,返回0。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.DEL index_name0 keyV

返回示例:

 (integer) 1

TVS.HDEL

类别说明
语法TVS.HDEL index_name key attribute_key [attribute_key ...]
时间复杂度O(1)
命令描述

在向量索引的数据记录(key)中,删除指定的attribute_key与其数值。

选项
  • index_name:向量索引名称。
  • key:该记录的主键标识,支持指定多个。
  • attribute_key:待操作的属性Key,支持指定多个。若需查询向量数据,需传入VECTOR关键字(必须大写)。
返回值
  • 执行成功:删除指定数据,并返回删除attribute_key的数量。
  • 若指定索引不存在,返回0。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.HDEL index_name0 keyc VECTOR

返回示例:

 (integer) 1

TVS.SCAN

类别说明
语法TVS.SCAN index_name cursor [MATCH pattern] [COUNT count]
时间复杂度O(N),N为该向量索引中Key的数量。
命令描述

在指定向量索引中,扫描符合条件的数据记录(key)。

选项
  • index_name:向量索引名称。
  • cursor:指定本次扫描的游标,从0开始。
  • pattern:模式匹配。
  • count:指定本次扫描的数量,默认为10。
返回值
  • 执行成功:返回一个数组:
    • 第一个元素:下次查询的游标,若已扫描完成,则返回0。
    • 第二个元素:本次查询的数据记录(key)名称。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TVS.SCAN index_name0 0

返回示例:

1) "0"
2) 1) "key0"
   2) "keyV"

TVS.KNNSEARCH

类别说明
语法TVS.KNNSEARCH index_name topN vector [filter_string] [param_key param_value]
时间复杂度O(log(N)),N为该向量索引中Key的数量。
命令描述

在指定向量索引中,对指定的向量(VECTOR)进行近邻查询,最多可返回topN条。

选项
  • index_name:向量索引名称。
  • topN:查询返回的数量,取值范围为[1,10000]。
  • vector:执行近邻查询的向量值。
  • filter_string:过滤条件。
    • 支持+-*/<>!=()&&||等操作符,暂不支持比较字符串之间的大小。例如create_time > 1663637425 && location == “Hangzhou”
    • 支持C语言格式,例如"creation_time > 1735"
  • param_keyparam_value:查询的运行参数,取值如下。

    ef_search:查询索引的时候,动态列表的长度,默认为100,取值范围为[1,1000],该值越大则查询精度越高,同时性能开销越大。该参数为HNSW算法的特定参数。

返回值
  • 执行成功:按距离近到远的顺序返回近邻的key及与该目标向量的距离。
  • 若指定的向量索引不存在,返回(empty array)
  • 其他情况返回相应的异常信息。
示例
请提前执行如下命令:
TVS.CREATEINDEX my_index_k 2 HNSW L2
TVS.HSET my_index_k key0 VECTOR [1,2] creation_time 1730
TVS.HSET my_index_k key1 VECTOR [3,4] creation_time 1740
TVS.HSET my_index_k key2 VECTOR [5,6] creation_time 1750

命令示例:

TVS.KNNSEARCH my_index_k 2 [3,3.1] "creation_time > 1735"

返回示例:

1) "key1"
2) "0.81000018119812012"
3) "key2"
4) "12.410000801086426"

TVS.MKNNSEARCH

类别说明
语法TVS.MKNNSEARCH index_name topN vector_count vector [vector ...] [filter_string] [param_key param_value]
时间复杂度Vector_count * O(log(N)),N为该向量索引中Key的数量。
命令描述

在指定向量索引中,批量对多条向量(VECTOR)进行近邻查询。

选项
  • index_name:向量索引名称。
  • topN:每条向量查询返回的数量,取值范围为[1,10000]。
  • vector_count :查询的向量数。
  • vector:执行近邻查询的向量值。
  • filter_string:过滤条件。
    • 支持+-*/<>!=()&&||等操作符,暂不支持比较字符串之间的大小。例如create_time > 1663637425 && location == “Hangzhou”
    • 支持C语言格式,例如"creation_time > 1735"
  • param_keyparam_value:查询的运行参数,取值如下。

    ef_search:查询索引的时候,动态列表的长度,默认为100,取值范围为[1,1000],该值越大则查询精度越高,同时会消耗更多的性能,降低查询速度。该参数为HNSW算法的特定参数。

返回值
  • 执行成功:按向量查询顺序返回多个查询结果数组,每个数组中按距离近到远的顺序返回近邻的key及与该目标向量的距离。
  • 若指定的向量索引不存在,返回(empty array)
  • 其他情况返回相应的异常信息。
示例
请提前执行如下命令:
TVS.CREATEINDEX my_index_m 2 HNSW L2
TVS.HSET my_index_m key0 VECTOR [1,2] creation_time 1730
TVS.HSET my_index_m key1 VECTOR [3,4] creation_time 1740
TVS.HSET my_index_m key2 VECTOR [5,6] creation_time 1750

命令示例:

TVS.MKNNSEARCH my_index_m 2 2 [3,4] [5,6] "creation_time > 1735"

返回示例:

1) 1) "key1"
   2) "0"
   3) "key2"
   4) "8"
2) 1) "key2"
   2) "0"
   3) "key1"
   4) "8"

TVS.MINDEXKNNSEARCH

类别说明
语法TVS.MINDEXKNNSEARCH index_count index_name [index_name ...] topN vector [filter_string] [param_key param_value]
时间复杂度Index_count * O(log(N)),N为该向量索引中Key的数量。
命令描述

在多个向量索引中,对指定的向量(VECTOR)进行近邻查询。

选项
  • index_count:向量索引的数量。
  • index_name:向量索引名称。
  • topN:查询返回的数量,取值范围为[1,10000],默认会查询出每个向量索引的topN个结果,并将所有查询结果进行聚合,返回距离最近的topN个结果。
  • vector:执行近邻查询的向量值。
  • filter_string:过滤条件。
    • 支持+-*/<>!=()&&||等操作符,暂不支持比较字符串之间的大小。例如create_time > 1663637425 && location == “Hangzhou”
    • 支持C语言格式,例如"creation_time > 1735"
  • param_keyparam_value:查询的运行参数,取值如下。

    ef_search:查询索引的时候,动态列表的长度,默认为100,取值范围为[1,1000],该值越大则查询精度越高,同时会消耗更多的性能,降低查询速度。该参数为HNSW算法的特定参数。

返回值
  • 执行成功:按距离近到远的顺序返回近邻的key及与该目标向量的距离。
  • 若指定的向量索引不存在,返回(empty array)
  • 其他情况返回相应的异常信息。
示例
请提前执行如下命令:
TVS.CREATEINDEX my_index_mk 2 HNSW L2
TVS.HSET my_index_mk key0 VECTOR [1,2] creation_time 1730
TVS.HSET my_index_mk key1 VECTOR [3,4] creation_time 1740
TVS.HSET my_index_mk key2 VECTOR [5,6] creation_time 1750
TVS.CREATEINDEX my_index_mx 2 HNSW L2
TVS.HSET my_index_mx key5 VECTOR [8,7] creation_time 1730
TVS.HSET my_index_mx key6 VECTOR [6,5] creation_time 1740
TVS.HSET my_index_mx key7 VECTOR [4,3] creation_time 1750

命令示例:

TVS.MINDEXKNNSEARCH 2 my_index_mk my_index_mx 2 [0,0]

返回示例:

1) "key0"
2) "5"
3) "key7"
4) "25"

TVS.MINDEXMKNNSEARCH

类别说明
语法TVS.MINDEXMKNNSEARCH index_count index_name [index_name ...] topN vector_count vector [vector ...] [filter_string] [param_key param_value]
时间复杂度Index_count * O(log(N)),N为该向量索引中Key的数量。
命令描述

在多个向量索引中,批量对多条向量(VECTOR)进行近邻查询。

选项
  • index_count:向量索引的数量。
  • index_name:向量索引名称。
  • topN:每条向量查询返回的数量,取值范围为[1,10000],默认会查询出每个向量索引的topN个结果,并将所有查询结果进行聚合,返回距离最近的topN个结果。
  • vector_count :查询的向量数。
  • vector:执行近邻查询的向量值。
  • filter_string:过滤条件。
    • 支持+-*/<>!=()&&||等操作符,暂不支持比较字符串之间的大小。例如create_time > 1663637425 && location == “Hangzhou”
    • 支持C语言格式,例如"creation_time > 1735"
  • param_keyparam_value:查询的运行参数,取值如下。

    ef_search:查询索引的时候,动态列表的长度,默认为100,取值范围为[1,1000],该值越大则查询精度越高,同时会消耗更多的性能,降低查询速度。该参数为HNSW算法的特定参数。

返回值
  • 执行成功:按向量查询顺序返回多个查询结果数组,每个数组中按距离近到远的顺序返回近邻的key及与该目标向量的距离。
  • 若指定的向量索引不存在,返回(empty array)
  • 其他情况返回相应的异常信息。
示例
请提前执行如下命令:
TVS.CREATEINDEX my_index_mk 2 HNSW L2
TVS.HSET my_index_mk key0 VECTOR [1,2] creation_time 1730
TVS.HSET my_index_mk key1 VECTOR [3,4] creation_time 1740
TVS.HSET my_index_mk key2 VECTOR [5,6] creation_time 1750
TVS.CREATEINDEX my_index_mx 2 HNSW L2
TVS.HSET my_index_mx key5 VECTOR [8,7] creation_time 1730
TVS.HSET my_index_mx key6 VECTOR [6,5] creation_time 1740
TVS.HSET my_index_mx key7 VECTOR [4,3] creation_time 1750

命令示例:

TVS.MINDEXMKNNSEARCH 2 my_index_mk my_index_mx 2 2 [0,0] [3,3]

返回示例:

1) 1) "key0"
   2) "5"
   3) "key7"
   4) "25"
2) 1) "key1"
   2) "1"
   3) "key7"
   4) "1"