TairVector is an in-house data structure that provides high-performance real-time storage and retrieval of vectors.

Overview

TairVector uses a multi-layer hash structure, as shown in the following figure.TairVectorTairVector provides two indexing algorithms: Hierarchical Navigable Small World (HNSW) and Flat Search.
  • HNSW: creates graph-based vector indexes to ensure high search accuracy while maintaining excellent real-time update performance.
  • Flat Search: implements exact match and fast data insertion. This algorithm is suitable for small datasets.
Additionally, TairVector supports multiple distance functions, such as Euclidean distance, inner product, and Jaccard distance. Compared with traditional vector retrieval services, TairVector has the following advantages:
  • Stores all data in memory and supports real-time index updates to reduce latency of read and write operations.
  • Uses an optimized data structure in memory to better utilize storage capacity.
  • Functions as an out-of-the-box data structure in a simple and efficient architecture without complex modules or dependencies.
Release notes
  1. TairVector was released on October 13, 2022 together with Tair DRAM-based instances that are compatible with Redis 6.0.
  2. A new version of TairVector that runs the 6.2.2.0 minor version was released on November 22, 2022 to support the Jaccard distance formula. Additionally, the TVS.GETINDEX command supports the index_data_size and attribute_data_size parameters to calculate the memory usage of each vector.
  3. A new version of TairVector that runs the 6.2.3.0 minor version was released on December 26, 2022 to support cluster instances in proxy mode. This new version of TairVector provides the FLOAT16 data type and the , TVS.MINDEXKNNSEARCH, , and TVS.MINDEXMKNNSEARCH commands.

Prerequisites

The instance is a Tair DRAM-based instance that is compatible with Redis 6.0. For more information, see DRAM-based instances.
Note A DRAM-based instance that runs Redis 5.0 cannot be upgraded to one that runs Redis 6.0. To use a DRAM-based instance that runs Redis 6.0, you must create one.

Precautions

  • The TairVector data that you want to manage is stored on the Tair instance.
  • The time to live (TTL) feature and the EXPIRE and MOVE commands are unavailable for TairVector.

Supported commands

Table 1. TairVector commands
TypeCommandSyntaxDescription
Vector index operationTVS.CREATEINDEXTVS.CREATEINDEX index_name dims algorithm distance_method [algo_param_key alog_param_value] ...

Creates a vector index based on the specified distance function and algorithm. The algorithm is used to create the index and perform queries. The index can be deleted only by running the TVS.DELINDEX command.

TVS.GETINDEXTVS.GETINDEX index_name

Queries the specified vector index and retrieves the metadata of the index.

TVS.DELINDEXTVS.DELINDEX index_name

Deletes the specified vector index and all data of the index.

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

Scans the vector indexes that meet specific criteria in the Tair instance.

Vector data operationTVS.HSETTVS.HSET index_name key attribute_key attribute_value [attribute_key attribute_value] ...

Inserts a vector into the index. If the vector already exists, the existing data is overwritten.

TVS.HGETALLTVS.HGETALL index_name key

Queries all the data records of the specified key in the specified vector index.

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

Queries the value of the attribute_key parameter in the specified key of the specified vector index.

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

Deletes the specified vectors from the specified vector index by using the key parameter.

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

Deletes the specified attributes of the specified vector from the vector index.

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

Scans the keys that meet specific criteria in the specified vector index.

Vector nearest-neighbor queryTVS.KNNSEARCHTVS.KNNSEARCH index_name topN vector [filter_string] [param_key param_value]

Queries the nearest-neighbor vectors of the specified vector in the specified vector index. Up to 10,000 vectors can be returned.

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

Queries the nearest-neighbor vectors of the specified vectors in the specified vector index.

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

Queries the nearest-neighbor vectors of the specified vector with multiple vector indexes.

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

Queries the nearest-neighbor vectors of the specified vectors with multiple vector indexes.

Note The following section describes command syntax used in this topic:
  • Uppercase keyword: the command keyword.
  • Italic: Words in italic indicate variable information that you supply.
  • [options]: optional parameters. Parameters that are not included in brackets are required.
  • AB: specifies that these parameters are mutually exclusive. Select one of two or more parameters.
  • ...: specifies to repeat the preceding content.

TVS.CREATEINDEX

ItemDescription
SyntaxTVS.CREATEINDEX index_name dims algorithm distance_method [algo_param_key alog_param_value] ...
Time complexityO(1)
Command description

Creates a vector index based on the specified distance function and algorithm. The algorithm is used to create the index and perform queries. The index can be deleted only by running the TVS.DELINDEX command.

Parameter
  • index_name: the name of the vector index.
  • dims: the dimension of a vector. Vectors inserted into the index must have the same dimension. Valid values: 1 to 32768.
  • algorithm: the algorithm used to create the index and perform queries. Valid values:
    • FLAT: uses the Flat Search algorithm to search for vectors without creating indexes. This algorithm is suitable for datasets that contain less than 10,000 records.
    • HNSW: uses HNSW graphs to create indexes and uses the HNSW algorithm to search for vectors. This algorithm is suitable for large datasets.
  • distance_method: the function used to calculate vector distance. Valid values:
    • L2: Euclidean distance formula
    • IP: inner product formula
    • JACCARD: Jaccard distance formula. If you select this value, you must set data_type to BINARY.

    If you set the distance_method parameter to a value other than JACCARD, the data_type parameter is set to FLOAT32 and cannot be changed.

  • algo_param_key and alog_param_value:
    • data_type: the data type of the vector. Valid values:
      • FLOAT32: a four-byte single-precision floating-point number.
      • FLOAT16: a two-byte half-precision floating-point number that conforms to the IEEE 754-2008 standard. This data type reduces the storage usage of vectors, but compromises data precision. Valid values: -65519 to 65519.
      • BINARY: a binary vector that can include only 0 and 1 and supports only the Jaccard distance formula.
    • HNSW: a specific parameter for indexes. Valid values:
      • ef_construct: the length of the dynamic array when you use the HNSW algorithm to create a vector index. Default value: 100. Valid values: 1 to 1000. The greater the value is, the higher the approximate nearest neighbor (ANN) search accuracy is. This results in more performance overheads.
      • M: the maximum number of outgoing neighbors on each layer in a graph index structure. Default value: 16. Valid values: 1 to 100. The greater the value is, the higher the approximate nearest neighbor (ANN) search accuracy is. This results in more performance overheads.
Output
  • If the operation is successful, OK is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

# Create a vector index that uses the HNSW algorithm and the Jaccard distance formula for vectors whose dimension is 2 and data type is BINARY. 
TVS.CREATEINDEX index_name0 2 HNSW JACCARD data_type BINARY

# Create a vector index that uses the HNSW algorithm and the Euclidean distance formula for vectors whose dimension is 2 and data type is FLOAT32. 
TVS.CREATEINDEX index_name1 2 HNSW L2

# Create a vector index that uses the HNSW algorithm and the inner product formula for vectors whose dimension is 2 and data type is FLOAT32. 
TVS.CREATEINDEX index_name2 2 HNSW IP

# Create a vector index that uses the Flat Search algorithm and the Euclidean distance formula for vectors whose dimension is 2 and data type is FLOAT32. 
TVS.CREATEINDEX index_name3 2 FLAT L2

# Create a vector index that uses the Flat Search algorithm and the inner product formula for vectors whose dimension is 2 and data type is FLOAT32. 
TVS.CREATEINDEX index_name4 2 FLAT IP

# Create a vector index that uses the Flat Search algorithm and the Jaccard distance formula for vectors whose dimension is 2 and data type is BINARY. 
TVS.CREATEINDEX index_name5 2 FLAT JACCARD data_type BINARY

Sample output:

OK

TVS.GETINDEX

ItemDescription
SyntaxTVS.GETINDEX index_name
Time complexityO(1)
Command description

Queries the specified vector index and retrieves the metadata of the index.

Parameter
  • index_name: the name of the vector index.
Output
  • If the operation is successful, the metadata of the vector index is returned.
  • If the specified vector index does not exist, (empty array) is returned.
  • Otherwise, an error message is returned.
Example

Run the following commands in advance:

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

Sample command (with the algorithm parameter set to HNSW):

TVS.GETINDEX my_index

Sample output:

 1) "M"                    // The maximum number of outgoing neighbors on each layer in a graph index structure. 
 2) "16"
 3) "ef_construct"         // The length of the dynamic array when you use the HNSW algorithm. 
 4) "100"
 5) "algorithm"            // The indexing algorithm. 
 6) "HNSW"
 7) "distance_method"      // The distance function. 
 8) "L2"
 9) "dimension"            // The dimension of the vectors. 
10) "2"
11) "index_name"           // The name of the index. 
12) "my_index"
13) "data_count"           // The data volume. 
14) "3"
15) "data_type"            // The data type of the vectors. 
16) "FLOAT32"
17) "index_data_size"      // The amount of memory used by vectors. Unit: bytes. 
18) "34668544"
19) "attribute_data_size"  // The amount of memory used by attribute information. Unit: bytes. 
20) "528"

TVS.DELINDEX

ItemDescription
SyntaxTVS.DELINDEX index_name
Time complexityO(N), in which N indicates the number of keys in the vector index.
Command description

Deletes the specified vector index and all data of the index.

Parameter
  • index_name: the name of the vector index.
Output
  • If the operation is successful, the vector index is deleted and 1 is returned.
  • If the specified vector index does not exist, 0 is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.DELINDEX index_name0

Sample output:

 (integer) 1

TVS.SCANINDEX

ItemDescription
SyntaxTVS.SCANINDEX cursor [MATCH pattern] [COUNT count]
Time complexityO(N), in which N indicates the number of vector indexes in the Tair instance.
Command description

Scans the vector indexes that meet specific criteria in the Tair instance.

Parameter
  • cursor: the cursor used in this scan. The cursor position starts from 0.
  • pattern: the pattern used in this scan.
  • count: the number of keys to be scanned. Default value: 10.
Output
  • If the operation is successful, an array is returned.
    • Element 1 of the array: the cursor used for the next scan. If the operation is successful, 0 is returned.
    • Element 2 of the array: the names of scanned vector indexs.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.SCANINDEX 0

Sample output:

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

TVS.HSET

ItemDescription
SyntaxTVS.HSET index_name key attribute_key attribute_value [attribute_key attribute_value] ...
Time complexityIf no indexes are created in this operation, the time complexity is O(1). Otherwise, the time complexity is O(log(N)), in which N indicates the number of keys in the vector index.
Command description

Inserts a vector into the index. If the vector already exists, the existing data is overwritten.

Parameter
  • index_name: the name of the vector index.
  • key: the primary key identifier of the vector. It can be deleted by running the TVS.DEL command.
  • attribute_key and attribute_value: the vector to be inserted in the key-value format.
    • To insert a vector, set attribute_key to VECTOR and attribute_value to a vector string that has the same dimension as that of the vector index specified by the dims parameter. Example: VECTOR [1,2]. You can write only a single vector to a key. If you write a vector more than once, the existing data is overwritten.
    • To insert other attributes, specify custom parameters related to these attributes. Examples: create_time 1663637425 and location Hangzhou.
Output
  • If the operation is successful, the number of vectors that are written to the vector index is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

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

Sample output:

(integer) 3

TVS.HGETALL

ItemDescription
SyntaxTVS.HGETALL index_name key
Time complexityO(1)
Command description

Queries all the data records of the specified key in the specified vector index.

Parameter
  • index_name: the name of the vector index.
  • key: the primary key identifier of the vector.
Output
  • If the operation is successful, all data records of the key are returned.
  • If the specified vector index or the key does not exist, (empty array) is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.HGETALL index_name0 key0

Sample output:

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

TVS.HMGET

ItemDescription
SyntaxTVS.HMGET index_name key attribute_key [attribute_key ...]
Time complexityO(1)
Command description

Queries the value of the attribute_key parameter in the specified key of the specified vector index.

Parameter
  • index_name: the name of the vector index.
  • key: the primary key identifier of the vector.
  • attribute_key: the attribute key to be queried. You can specify multiple keys. If you want to query a specific vector, you must set the attribute_key parameter to VECTOR.
Output
  • If the operation is successful, the value of the attribute_key parameter is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.HMGET index_name0 key0 create_time location VECTOR

Sample output:

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

TVS.DEL

ItemDescription
SyntaxTVS.DEL index_name key [key ...]
Time complexityO(1)
Command description

Deletes the specified vectors from the specified vector index by using the key parameter.

Parameter
  • index_name: the name of the vector index.
  • key: the primary key identifier of the vector. You can specify multiple keys.
Output
  • If the operation is successful, the specified vectors are deleted and the number of deleted vectors is returned.
  • If the specified vector index does not exist, 0 is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.DEL index_name0 keyV

Sample output:

 (integer) 1

TVS.HDEL

ItemDescription
SyntaxTVS.HDEL index_name key attribute_key [attribute_key ...]
Time complexityO(1)
Command description

Deletes the specified attributes of the specified vector from the vector index.

Parameter
  • index_name: the name of the vector index.
  • key: the primary key identifier of the vector. You can specify multiple keys.
  • attribute_key: the attribute key to be deleted. You can specify multiple keys. If you want to query a specific vector, you must set the attribute_key parameter to VECTOR.
Output
  • If the operation is successful, the specified attributes are deleted and the number of deleted attributes is returned.
  • If the specified vector index does not exist, 0 is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.HDEL index_name0 keyc VECTOR

Sample output:

 (integer) 1

TVS.SCAN

ItemDescription
SyntaxTVS.SCAN index_name cursor [MATCH pattern] [COUNT count]
Time complexityO(N), in which N indicates the number of keys in the vector index.
Command description

Scans the keys that meet specific criteria in the specified vector index.

Parameter
  • index_name: the name of the vector index.
  • cursor: the cursor used in this scan. The cursor position starts from 0.
  • pattern: the pattern used in this scan.
  • count: the number of keys to be scanned. Default value: 10.
Output
  • If the operation is successful, an array is returned.
    • Element 1 of the array: the cursor used for the next scan. If the operation is successful, 0 is returned.
    • Element 2 of the array: the names of scanned keys.
  • Otherwise, an error message is returned.
Example

Sample command:

TVS.SCAN index_name0 0

Sample output:

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

TVS.KNNSEARCH

ItemDescription
SyntaxTVS.KNNSEARCH index_name topN vector [filter_string] [param_key param_value]
Time complexityO(log(N)), in which N indicates the number of keys in the vector index.
Command description

Queries the nearest-neighbor vectors of the specified vector in the specified vector index. Up to 10,000 vectors can be returned.

Parameter
  • index_name: the name of the vector index.
  • topN: the number of vectors to return. Valid values: 1 to 10000.
  • vector: the vector whose nearest neighbors you want to query.
  • filter_string: the filtering conditions.
    • Supports operators such as + - * / < > ! = ( ) & & ||. You cannot compare the sizes of strings. Example: create_time > 1663637425 && location == "Hangzhou".
    • Supports the C language. Example: "creation_time > 1735".
  • param_key and param_value: the operational parameters of the query. Valid value:

    ef_search: the length of the dynamic array. Default value: 100. Valid values: 1 to 1000. The greater the value is, the higher the search accuracy is. This results in more performance overheads. This parameter is available only if you use the HNSW indexing algorithm.

Output
  • If the operation is successful, the keys of the neighbor vectors are returned in ascending order of their distances to the specified vector.
  • If the specified vector index does not exist, (empty array) is returned.
  • Otherwise, an error message is returned.
Example
Run the following commands in advance:
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

Sample command:

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

Sample output:

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

TVS.MKNNSEARCH

ItemDescription
SyntaxTVS.MKNNSEARCH index_name topN vector_count vector [vector ...] [filter_string] [param_key param_value]
Time complexityvector_count × O(log(N)), in which N indicates the number of keys in the vector index.
Command description

Queries the nearest-neighbor vectors of the specified vectors in the specified vector index.

Parameter
  • index_name: the name of the vector index.
  • topN: the number of neighbor vectors to return for each specified vector. Valid values: 1 to 10000.
  • vector_count: the number of the specified vectors.
  • vector: the vector whose nearest neighbors you want to query.
  • filter_string: the filtering conditions.
    • Supports operators such as + - * / < > ! = ( ) & & ||. You cannot compare the sizes of strings. Example: create_time > 1663637425 && location == "Hangzhou".
    • Supports the C language. Example: "creation_time > 1735".
  • param_key and param_value: the operational parameters of the query. Valid value:

    ef_search: the length of the dynamic array. Default value: 100. Valid values: 1 to 1000. The greater the value is, the higher the search accuracy is. This results in more performance overheads and slower queries. This parameter is available only if you use the HNSW indexing algorithm.

Output
  • If the operation is successful, the results are returned in arrays. Each array contains the neighbor vector keys in ascending order of their distances to each specified vector.
  • If the specified vector index does not exist, (empty array) is returned.
  • Otherwise, an error message is returned.
Example
Run the following commands in advance:
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

Sample command:

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

Sample output:

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

TVS.MINDEXKNNSEARCH

ItemDescription
SyntaxTVS.MINDEXKNNSEARCH index_count index_name [index_name ...] topN vector [filter_string] [param_key param_value]
Time complexityindex_count × O(log(N)), in which N indicates the number of keys in the vector index.
Command description

Queries the nearest-neighbor vectors of the specified vector with multiple vector indexes.

Parameter
  • index_count: the number of vector indexes.
  • index_name: the names of these vector indexes.
  • topN: the number of vectors to be returned. By default, the system queries the specified number of vectors with each index, aggregates these obtained vectors, and returns the specified number of vectors that are the nearest to the specified vector. Valid values: 1 to 10000.
  • vector: the vector whose nearest neighbors you want to query.
  • filter_string: the filtering conditions.
    • Supports operators such as + - * / < > ! = ( ) & & ||. You cannot compare the sizes of strings. Example: create_time > 1663637425 && location == "Hangzhou".
    • Supports the C language. Example: "creation_time > 1735".
  • param_key and param_value: the operational parameters of the query. Valid value:

    ef_search: the length of the dynamic array. Default value: 100. Valid values: 1 to 1000. The greater the value is, the higher the search accuracy is. This results in more performance overheads and slower queries. This parameter is available only if you use the HNSW indexing algorithm.

Output
  • If the operation is successful, the keys of the neighbor vectors are returned in ascending order of their distances to the specified vector.
  • If the specified vector index does not exist, (empty array) is returned.
  • Otherwise, an error message is returned.
Example
Run the following commands in advance:
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

Sample command:

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

Sample output:

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

TVS.MINDEXMKNNSEARCH

ItemDescription
SyntaxTVS.MINDEXMKNNSEARCH index_count index_name [index_name ...] topN vector_count vector [vector ...] [filter_string] [param_key param_value]
Time complexityindex_count × O(log(N)), in which N indicates the number of keys in the vector index.
Command description

Queries the nearest-neighbor vectors of the specified vectors with multiple vector indexes.

Parameter
  • index_count: the number of vector indexes.
  • index_name: the names of these vector indexes.
  • topN: the number of vectors to be returned for each vector. By default, the system queries the specified number of vectors with each index, aggregates these obtained vectors, and returns the specified number of vectors that are the nearest to each specified vector. Valid values: 1 to 10000.
  • vector_count: the number of the specified vectors.
  • vector: the vectors whose nearest neighbors you want to query.
  • filter_string: the filtering conditions.
    • Supports operators such as + - * / < > ! = ( ) & & ||. You cannot compare the sizes of strings. Example: create_time > 1663637425 && location == "Hangzhou".
    • Supports the C language. Example: "creation_time > 1735".
  • param_key and param_value: the operational parameters of the query. Valid value:

    ef_search: the length of the dynamic array. Default value: 100. Valid values: 1 to 1000. The greater the value is, the higher the search accuracy is. This results in more performance overheads and slower queries. This parameter is available only if you use the HNSW indexing algorithm.

Output
  • If the operation is successful, the results are returned in arrays. Each array contains the neighbor vector keys in ascending order of their distances to each specified vector.
  • If the specified vector index does not exist, (empty array) is returned.
  • Otherwise, an error message is returned.
Example
Run the following commands in advance:
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

Sample command:

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

Sample output:

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