TairSearch is a full-text search data structure developed in-house based on Redis modules instead of Lucene or other open source search engine software libraries. TairSearch uses query syntax that is similar to that of Elasticsearch.

Overview

Compared with Elasticsearch, TairSearch has the following advantages:
  • Low latency and high performance: provides millisecond-level write and full-text search capabilities based on the ultra-high computing power of Tair.
  • Incremental and partial updates: supports partial updates of indexes and incremental updates of documents, including adding, updating, removing, and auto-incrementing fields.
  • Flexible syntax: provides custom sorting order and supports the JSON syntax that allows bool, match, term, and paging queries. This syntax is similar to that of Elasticsearch.
  • Aggregate query: supports terms, metrics, and filter aggregations. For more information, see Aggregations.
  • Auto-complete suggestion: supports fuzzy match with prefixes and automatic completion for search operations.
  • Custom tokenizer: provides tokenizers for popular languages such as Chinese and English. You can also use a custom tokenizer.
Release notes
  1. On March 11, 2022, TairSearch was released with Tair V1.7.27.
  2. On May 24, 2022, Tair V1.8.5 was released to add support for the TairSearch aggregation feature.
  3. On September 6, 2022, Tair V5.0.15 was released to add support for the TFT.MSEARCH command.

Best practices

Prerequisites

A DRAM-based instance of the ApsaraDB for Redis Enhanced Edition (Tair) that runs the minor version of 1.7.27 or later is created. For more information about DRAM-based instances, see DRAM-based instances.
Note We recommend that you update your instance to the latest minor version for more features and higher stability. For more information, see Update the minor version. If your instance is a cluster or read/write splitting instance, we recommend that you update the proxy nodes in the instance to the latest minor version. This ensures that all commands can be run as expected. For more information about cluster and read/write splitting instances, see Cluster master-replica instances and Read/write splitting instances.

Precautions

  • The TairSearch data that you want to manage is stored on the Tair instance.
  • To reduce memory usage, we recommend that you perform the following operations:
    • When you create indexes, set index to true for document fields that you want to specify as inverted fields. For other document fields, set index to false.
    • Specify the includes and excludes parameters of the _source field to filter out document fields that you do not need and save fields that you need.
  • Do not add a large number of documents to a single index. Add the documents to multiple indexes. We recommend that you keep the number of documents per index within 500 million to prevent data skew in cluster instances, balance read and write traffic, and reduce the number of large keys and hotkeys.

Supported commands

Table 1. Full-text search commands
Command Syntax Description
TFT.CREATEINDEX TFT.CREATEINDEX index mappings

Creates an index and a mapping for the index. The syntax used to create a mapping is similar to that used to create an explicit mapping in Elasticsearch. For more information, see Explicit mapping. You must create an index before you can add documents to the index.

TFT.UPDATEINDEX TFT.UPDATEINDEX index mappings

Adds a properties field to the specified index. The field that you want to add cannot have the same name as an existing one. Otherwise, the field cannot be added.

TFT.GETINDEX TFT.GETINDEX index

Obtains the mapping content of an index.

TFT.ADDDOC TFT.ADDDOC index document [WITH_ID doc_id]

Adds a document to an index. You can specify a unique ID for the document in the index by using WITH_ID doc_id. If the document ID already exists, the existing ID is overwritten. If you do not specify WITH_ID doc_id, a document ID is automatically generated. By default, WITH_ID doc_id is not specified.

TFT.MADDDOC TFT.MADDDOC index document doc_id [document1 doc_id1] ...

Adds multiple documents to an index. Each document must have a document ID that is specified by doc_id.

TFT.UPDATEDOCFIELD TFT.UPDATEDOCFIELD index doc_id document
Updates the document specified by doc_id in an index. If the document fields that you want to update are mapped and indexed fields, the fields must be of the same type as those used by the mapping. If the fields are not indexed fields, the fields to be updated can be of a random type.
Note If the fields already exist, the document is updated. If the fields do not exist, the fields are added. If the document does not exist, the document is automatically created. In this case, the command is equivalent to TFT.ADDDOC.
TFT.DELDOCFIELD TFT.DELDOCFIELD index doc_id field [field1 field2 ...]
Deletes the specified field from the document specified by doc_id in an index. If the field is an indexed field, the information of the field is also deleted from the index.
Note If the field does not exist, the operation cannot be performed. For example, the field may not exist because it is filtered out by using _source.
TFT.INCRLONGDOCFIELD TFT.INCRLONGDOCFIELD index doc_id field increment
Adds an increment to the specified field in the document specified by doc_id in an index. The increment can be a positive or negative integer. The data type of the field can only be LONG or INTEGER.
Note If the document does not exist, the document is automatically created. In this case, the existing value of the field is 0, and the updated field value is obtained by adding the increment value to the existing field value. If the field does not exist, the operation cannot be performed. For example, the field may not exist because it is filtered out by using _source.
TFT.INCRFLOATDOCFIELD TFT.INCRFLOATDOCFIELD index doc_id field increment
Adds an increment to the specified field in the document specified by doc_id in an index. The increment can be a positive or negative floating-point number. The data type of the field can be INTEGER, LONG, or DOUBLE.
Note If the document does not exist, the document is automatically created. In this case, the existing value of the field is 0, and the updated field value is obtained by adding the increment value to the existing field value. If the field does not exist, the operation cannot be performed. For example, the field may not exist because it is filtered out by using _source.
TFT.GETDOC TFT.GETDOC index doc_id

Obtains the content of the document specified by doc_id in an index.

TFT.EXISTS TFT.EXISTS index doc_id

Checks whether the document specified by doc_id exists in an index.

TFT.DOCNUM TFT.DOCNUM index

Obtains the number of documents in an index.

TFT.SCANDOCID TFT.SCANDOCID index cursor [MATCH *value*] [COUNT count]

Obtains the IDs of all documents in an index.

TFT.DELDOC TFT.DELDOC index doc_id [doc_id] ...

Deletes the document specified by doc_id from an index. Multiple document IDs can be specified.

TFT.DELALL TFT.DELALL index

Deletes all documents from an index but retains the index.

TFT.SEARCH TFT.SEARCH index query

Queries the documents in an index. The query syntax is similar to the Query Domain Specific Language (DSL) syntax used in Elasticsearch. For more information, see Query DSL.

TFT.MSEARCH TFT.MSEARCH index_count index [index1] ... query

Queries documents in multiple indexes that have mappings set to the same value by using the query clause and gathers the results from these indexes. Then, the results are rated, sorted, aggregated, and returned.

DEL DEL key [key ...] Deletes one or more TairSearch keys.
Table 2. Auto-complete commands
Command Syntax Description
TFT.ADDSUG TFT.ADDSUG index text weight [text weight] ...

Adds one or more auto-complete texts and their weights to the specified index.

TFT.DELSUG TFT.DELSUG index text [text] ...

Deletes one or more auto-complete texts from the specified index.

TFT.SUGNUM TFT.SUGNUM index

Obtains the number of auto-complete texts in the specified index.

TFT.GETSUG TFT.GETSUG index prefix [MAX_COUNT count] [FUZZY]

Obtains the auto-complete texts that can be matched based on the specified prefix. Texts are returned in descending order of weights.

TFT.GETALLSUGS TFT.GETALLSUGS index

Obtains the full auto-complete texts in the specified index.

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.

TFT.CREATEINDEX

Item Description
Syntax TFT.CREATEINDEX index mappings
Command description

Creates an index and a mapping for the index. The syntax used to create a mapping is similar to that used to create an explicit mapping in Elasticsearch. For more information, see Explicit mapping. You must create an index before you can add documents to the index.

Note To prevent large keys from being generated, you can split large indexes into small indexes and devise load distribution rules to write data to different indexes. When you create these indexes, make sure that they have the mappings parameter set to the same value.After these indexes are created, you can query them by using TFT.MSEARCH.
Parameter
  • index: the name of the index that you want to manage.
  • mappings: the mapping content. The following syntax is supported:
    • dynamic: the mapping mode. The strict mapping mode is supported. Only fields that have been specified in properties can be written. If you do not specify the mapping mode, non-strict mapping is used. In non-strict mode, the system does not check whether fields to be written have been specified in properties.
    • enabled: forcefully checks whether the field types in a document to be written are the same as those specified in properties. If they are not the same, the document cannot be written. Valid values: true and false. The default value is true, which indicates that a forceful check is performed. This parameter takes effect only for non-indexed fields (index set to false). For indexed fields, a forceful check is performed.
    • _source: the source of the original document. This parameter does not affect the creation of field indexes. Valid values:
      enabled: specifies whether to store the original document. Valid values:
      • true: stores the original document. By default, enabled is set to true and all fields in the document are stored.

        You can set excludes to specify the fields that you do not want to store in the original document and includes to specify the fields that you want to store. Wildcards are accepted. If a field is specified by both excludes and includes, excludes takes precedence over includes and the field is not stored in the original document.

        Example 1: "_source":{"enabled":true} specifies to store all fields and works like "_source":{"enabled":true,"excludes":[],"includes":[]}.

        Example 2: "_source":{"enabled":true,"excludes":[],"includes":["id","name"]} specifies to store only id and name fields.

      • false: does not store the original document.
    • properties: a collection of mapped fields. You can set the following attributes for each field:
      • index: specifies whether to set the field to an index field. Default value: true. Valid values:
        • true: sets the field to an index field. In this case, you can query documents only by using index fields. This is the default value.

          Tair stores the original documents of all index fields in memory. If _source is set to "enabled":false for this field, the returned original documents of a query do not contain this field.

        • false: does not set the field to an index field.
      • boost: the weight of the field. Default value: 1. The parameter value must be a positive floating-point number. Tair automatically calculates the estimated relative score of each field.
      • type: the data type of the field. Valid values:
        • keyword: a string that cannot be split. The following parameters can be specified for the string:
          • ignore_above: the maximum number of characters that can be contained in a keyword string. Default value: 128. Example: "ignore_above":128.
        • text: a string that can be parsed by a tokenizer and then stored in an index. The following parameters can be specified for the string:
          • analyzer: the tokenizer that parses the text value and then stores the value in the index. Valid values: standard, chinese, arabic, cjk, czech, brazilian, german, greek, persian, french, dutch, russian, and jieba. The default value is standard, which indicates an English tokenizer. If you want a Chinese tokenizer, we recommend that you use jieba because it performs better than chinese. For example, "analyzer":"jieba" specifies to use the jieba tokenizer.
          • search_analyzer: the tokenizer that is used in the search. The supported tokenizer types are the same as those supported by the analyzer parameter. The default value of this parameter is the same as that of the analyzer parameter.
        • long: the LONG data type. You can convert a point in time into a UNIX timestamp and store the timestamp as a piece of LONG-typed data.
        • integer: the INTEGER data type.
        • double: the DOUBLE data type.
Output
  • If the operation is successful, OK is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.CREATEINDEX idx:product '{"mappings":{"_source":{"enabled":true},"properties":{"product_id":{"type":"keyword","ignore_above":128},"product_name":{"type":"text"},"product_title":{"type":"text","analyzer":"jieba"},
"price":{"type":"double"}}}}'

# Create a product ID (product_id) of the keyword type and set the length limit of the ID to 128 characters. 
# Create a product name (product_name) of the text type. 
# Create a product title (product_title) of the text type and set analyzer to jieba. 
# Create a price (price) of the double type. 

Sample output:

OK

TFT.UPDATEINDEX

Item Description
Syntax TFT.UPDATEINDEX index mappings
Command description

Adds a properties field to the specified index. The field that you want to add cannot have the same name as an existing one. Otherwise, the field cannot be added.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • mappings: the mapping content. You do not need to specify parameters such as dynamic and _source. You can specify only properties that you want to add.
Note For more information about the mappings parameter, see the "TFT.CREATEINDEX" section of this topic.
Output
  • If the operation is successful, OK is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.UPDATEINDEX idx:product '{"mappings":{"properties":{"product_group":{"type":"text","analyzer":"chinese"}}}}'

Sample output:

OK

TFT.GETINDEX

Item Description
Syntax TFT.GETINDEX index
Command description

Obtains the mapping content of an index.

Parameter
  • index: the name of the index that you want to manage by running this command.
Output
  • If the operation is successful, the JSON-typed mapping content of the index is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.GETINDEX idx:product

Sample output:

{"idx:product0310":{"mappings":{"_source":{"enabled":true,"excludes":[],"includes":["product_id"]},"dynamic":"false","properties":{"price":{"boost":1.0,"enabled":true,"ignore_above":-1,"index":true,"similarity":"classic","type":"double"},"product_id":{"boost":1.0,"enabled":true,"ignore_above":128,"index":true,"similarity":"classic","type":"keyword"},"product_name":{"boost":1.0,"enabled":true,"ignore_above":-1,"index":true,"similarity":"classic","type":"text"},"product_title":{"analyzer":"chinese","boost":1.0,"enabled":true,"ignore_above":-1,"index":true,"similarity":"classic","type":"text"}}}}}

TFT.ADDDOC

Item Description
Syntax TFT.ADDDOC index document [WITH_ID doc_id]
Command description

Adds a document to an index. You can specify a unique ID for the document in the index by using WITH_ID doc_id. If the document ID already exists, the existing ID is overwritten. If you do not specify WITH_ID doc_id, a document ID is automatically generated. By default, WITH_ID doc_id is not specified.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • document: the JSON-typed document that you want to add to the index.
    Note If you specify _source and includes to retain only specific fields, only the fields specified by includes are retained when you add a document to the index or update a document added to the index.
  • WITH_ID doc_id: specifies whether to configure the ID of the document. If yes, you must also enter a string as the doc_id value.
Output
  • If the operation is successful, the JSON-typed document ID is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.ADDDOC idx:product '{"product_id":"product test"}' WITH_ID 00001

Sample output:

"{\"_id\":\"00001\"}"

TFT.MADDDOC

Item Description
Syntax TFT.MADDDOC index document doc_id [document1 doc_id1] ...
Command description

Adds multiple documents to an index. Each document must have a document ID that is specified by doc_id.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • document: the JSON-typed document that you want to add to the index.
    Note If you specify _source and includes to retain only specific fields, only the fields specified by includes are retained when you add a document to the index or update a document added to the index.
  • doc_id: the ID of the document. The value is a string.
Output
  • If the operation is successful, OK is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.MADDDOC idx:product '{"product_id":"test1"}' 00011 '{"product_id":"test2"}' 00012

Sample output:

OK

TFT.UPDATEDOCFIELD

Item Description
Syntax TFT.UPDATEDOCFIELD index doc_id document
Command description
Updates the document specified by doc_id in an index. If the document fields that you want to update are mapped and indexed fields, the fields must be of the same type as those used by the mapping. If the fields are not indexed fields, the fields to be updated can be of a random type.
Note If the fields already exist, the document is updated. If the fields do not exist, the fields are added. If the document does not exist, the document is automatically created. In this case, the command is equivalent to TFT.ADDDOC.
Parameter
  • index: the name of the index that you want to manage by running this command.
  • doc_id: the ID of the document.
  • document: the updated JSON-typed document content.
    Note If you specify _source and includes to retain only specific fields, only the fields specified by includes are retained when you add a document to the index or update a document added to the index.
Output
  • If the operation is successful, OK is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.UPDATEDOCFIELD idx:product 00011 '{"product_id":"test8","product_group":"BOOK"}'

Sample output:

OK

TFT.DELDOCFIELD

Item Description
Syntax TFT.DELDOCFIELD index doc_id field [field1 field2 ...]
Command description
Deletes the specified field from the document specified by doc_id in an index. If the field is an indexed field, the information of the field is also deleted from the index.
Note If the field does not exist, the operation cannot be performed. For example, the field may not exist because it is filtered out by using _source.
Parameter
  • index: the name of the index that you want to manage by running this command.
  • doc_id: the ID of the document.
  • field: the field that you want to delete.
Output
  • If the operation is successful, the number of deleted fields is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.DELDOCFIELD idx:product 00011 product_group

Sample output:

(integer) 1

TFT.INCRLONGDOCFIELD

Item Description
Syntax TFT.INCRLONGDOCFIELD index doc_id field increment
Command description
Adds an increment to the specified field in the document specified by doc_id in an index. The increment can be a positive or negative integer. The data type of the field can only be LONG or INTEGER.
Note If the document does not exist, the document is automatically created. In this case, the existing value of the field is 0, and the updated field value is obtained by adding the increment value to the existing field value. If the field does not exist, the operation cannot be performed. For example, the field may not exist because it is filtered out by using _source.
Parameter
  • index: the name of the index that you want to manage by running this command.
  • doc_id: the ID of the document.
  • field: the field to which you want to add an increment. The data type of the field can only be LONG or INTEGER.
  • increment: the increment value that you want to add to the field. The value must be an integer. You can specify a negative integer.
Output
  • If the operation is successful, the updated field value is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.INCRLONGDOCFIELD idx:product 00011 stock 100

Sample output:

(integer)100

TFT.INCRFLOATDOCFIELD

Item Description
Syntax TFT.INCRFLOATDOCFIELD index doc_id field increment
Command description
Adds an increment to the specified field in the document specified by doc_id in an index. The increment can be a positive or negative floating-point number. The data type of the field can be INTEGER, LONG, or DOUBLE.
Note If the document does not exist, the document is automatically created. In this case, the existing value of the field is 0, and the updated field value is obtained by adding the increment value to the existing field value. If the field does not exist, the operation cannot be performed. For example, the field may not exist because it is filtered out by using _source.
Parameter
  • index: the name of the index that you want to manage by running this command.
  • doc_id: the ID of the document.
  • field: the field to which you want to add an increment. The data type of the field can be LONG, INTEGER, or DOUBLE.
  • increment: the increment value that you want to add to the field. The value can be a positive or negative floating-point number.
Output
  • If the operation is successful, the updated field value is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.INCRFLOATDOCFIELD idx:product 00011 stock 299.6

Sample output:

"299.6"

TFT.GETDOC

Item Description
Syntax TFT.GETDOC index doc_id
Command description

Obtains the content of the document specified by doc_id in an index.

Parameter
  • index: the name of the index that you want to manage.
  • doc_id: the ID of the document.
Output
  • If the operation is successful, the ID and content of the document are returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.GETDOC idx:product 00011

Sample output:

"{\"_id\":\"00011\",\"_source\":{\"product_id\":\"test8\"}}"

TFT.EXISTS

Item Description
Syntax TFT.EXISTS index doc_id
Command description

Checks whether the document specified by doc_id exists in an index.

Parameter
  • index: the name of the index that you want to manage.
  • doc_id: the ID of the document.
Output
    • If the operation is successful and the document exists, a value of 1 is returned.
    • If the operation is successful and the field or document does not exist, a value of 0 is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.EXISTS idx:product 00011

Sample output:

(integer) 1

TFT.DOCNUM

Item Description
Syntax TFT.DOCNUM index
Command description

Obtains the number of documents in an index.

Parameter
  • index: the name of the index that you want to manage by running this command.
Output
  • If the operation is successful, the number of documents in the index is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.DOCNUM idx:product

Sample output:

(integer) 3

TFT.SCANDOCID

Item Description
Syntax TFT.SCANDOCID index cursor [MATCH *value*] [COUNT count]
Command description

Obtains the IDs of all documents in an index.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • cursor: the cursor used in this scan.
  • MATCH *value*: the matching pattern. value specifies the value that you use for matching. Example: MATCH *redis*.
  • COUNT count: the maximum number of items that can be scanned at a time. Default value: 100.
Output
  • If the operation is successful, an array is returned.
    • The first element of the array is the cursor used for the next scan. If the index is scanned, a value of 0 is returned.
    • The second element of the array is the IDs of the documents that are obtained in this scan.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.SCANDOCID idx:product 0 COUNT 3

Sample output:

1) "0"
2) 1) "00001"
   2) "00011"
   3) "00012"

TFT.DELDOC

Item Description
Syntax TFT.DELDOC index doc_id [doc_id] ...
Command description

Deletes the document specified by doc_id from an index. Multiple document IDs can be specified.

Parameter
  • index: the name of the index that you want to manage.
  • doc_id: the ID of the document.
Output
  • If the operation is successful, the number of deleted documents is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.DELDOC idx:product 00011 00014

Sample output:

"1"    # In this example, the document with an ID of 00014 does not exist. In this case, the 00011 document is deleted only and a value of 1 is returned. 

TFT.DELALL

Item Description
Syntax TFT.DELALL index
Command description

Deletes all documents from an index but retains the index.

Parameter
  • index: the name of the index that you want to manage.
  • doc_id: the ID of the document.
Output
  • If the operation is successful, OK is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.DELALL idx:product

Sample output:

OK

TFT.SEARCH

Item Description
Syntax TFT.SEARCH index query
Command description

Queries the documents in an index. The query syntax is similar to the Query Domain Specific Language (DSL) syntax used in Elasticsearch. For more information, see Query DSL.

Parameter

index: the name of the index that you want to manage. query: the Query DSL statement that is similar to the syntax used in Elasticsearch. The following fields are supported:

  • query: the query clause. The following syntax is supported:
    • match: the basic match query. The following parameters are supported:

      In scenarios that do not require document characters to be broken into individual tokens or do not require fuzzy match, we recommend that you use commands such as term and prefix to improve query efficiency.

      • query: the documents in the index obtained by using the query.
        Note
        • If fuzzy match is disabled by using fuzziness, documents obtained by the query are broken into individual tokens by a tokenizer specified by analyzer. You can also specify the relationship between tokens by using operator and the minimum number of tokens that need to be matched by using minimum_should_match.
        • If fuzzy match is enabled by using fuzziness, the preceding parameters are invalid. In this case, you can specify prefix_length.
      • analyzer: the tokenizer used by the match statement. Valid values: standard, chinese, arabic, cjk, czech, brazilian, german, greek, persian, french, dutch, russian, and jieba. The default value is standard, which indicates an English tokenizer. To parse Chinese characters, you can use jieba.
      • minimum_should_match: the minimum number of tokens that need to be matched. The tokenizer breaks the query statement into tokens. This parameter takes effect when fuzzy match is disabled and operator is set to OR.
      • operator: the relationship between tokens. Valid values: AND and OR. Default value: OR. For example, '{"query":{"match":{"f0":{"query":"redis cluster","operator":"OR"}}}}' specifies that the search condition is met when "redis" or "cluster" is contained in the documents for which you want to perform a query.
      • fuzziness: specifies whether to enable fuzzy match for the query. By default, fuzzy match is disabled. "fuzziness":1 specifies that fuzzy match is enabled. Example: '{"query":{"match":{"f0":{"query":"excelentl","fuzziness":1}}}}'.
      • prefix_length: the number of start characters that must be retained for a fuzzy match. Default value: 0. This parameter is valid only when fuzzy match is enabled.
    • term: the token query. If this parameter is specified, the query statement is not split. This query type is more efficient than the match query. The token query supports all field types. Examples: '{"query":{"term":{"f0":{"value":"redis","boost": 2.0}}}}' and '{"query":{"term":{"f0":"redis"}}}'.
    • terms: the multi-token query. A maximum of 1024 tokens are allowed in each multi-token query. Example: '{"query":{"terms":{"f0":["redis","excellent"]}}}'.
    • range: the range query. This parameter supports all field types. Valid values: It (less than), gt (greater than), Ite (less than or equal to), and gte (greater than or equal to). Example: '{"query":{"range":{"f0":{"lt":"abcd","gt":"ab"}}}}'.
    • wildcard: the wildcard query. Format: "wildcard":{"field to query":{"value":"query content"}}. Supported wildcards: * and ?. Example: '{"query":{"wildcard":{"f0":{"value":"*b?Se"}}}}'.
    • prefix: the prefix query. For example, '{"query":{"prefix":{"f0":"abcd"}}' specifies to query documents whose f0 fields start with abcd.
    • bool: the compound query. A maximum of 1024 tokens are allowed in each compound query. Valid values:
      • must: The query results match all query clauses in the must list. For example, '{"query":{"bool":{"must":[{"match":{"DB":"redis"}},{"match":{"Architectures":"cluster"}}]}}}' specifies that the type of the database that you want to query is Redis and the architecture of the instance that contains the database is cluster.
      • must_not: The query results do not match any query clauses in the must_not list.
      • should: the should list. If bool is set to should, the query results must match one query clause in this list. You can set the minimum_should_match parameter.
      • minimum_should_match: specifies the minimum number of query clauses that must be matched. This parameter must be used together with should. If a bool statement contains only should, minimum_should_match is set to 1 by default. If the bool statement also contains must or must_not, minimum_should_match is set to 0 by default. For example, '{"query":{"bool":{"minimum_should_match":1,"should":[{"match":{"DB":"redis"}},{"match":{"Architectures":"cluster"}}]}}}' specifies that the type of the database that you want to query is Redis or the architecture of the instance that contains the database is cluster.
      Note A bool statement can have all types of query clauses nested within it, such as bool clauses. Example: TFT.SEARCH idx:product '{"query":{"bool":{"must":[{"term":{"product_name":"apple"}},{"bool":{"minimum_should_match":1,"should":[{"term":{"price":19.5}},{"term":{"product_id":"fruits_2"}}]}}]}}}'.
    • dis_max: the compound query for best match. By default, this parameter returns documents that match one or more query clauses. If a returned document matches multiple query clauses, the dis_max query assigns the document the highest score from the matching clauses and a tie-breaking increment to the document score if tie_breaker is specified.

      Valid values of tie_breaker: 0 to 1. Default value: 0. After tie_breaker is specified, the document score can be calculated based on the following formula: Score from a matching clause that has the highest score + (Scores from other matching clauses × tie_breaker value). Assume that doc1 matches three query clauses whose document scores are 5, 1, and 3 and a tie_break value of 0.5 is specified. In this case, the score of doc1 can be calculated by using this formula: Score of doc1 = 5 + [(1 + 3) × 0.5].

      Example: '{"query":{"dis_max":{"queries":[{"term":{"f0":"redis"}},{"term":{"f1":"database"}},{"match":{"title":"redis memory database"}}],"tie_breaker": 0.5}}}'.

    • constant_score: the compound query that returns a constant score. This query wraps another query and returns a constant score equal to the query boost for every document in the filter. The boost value is of the double type, and the default boost value is 1.0. Example: '{"query":{"constant_score":{"filter":{"term":{"f0":"abc"}},"boost":1.2}}}'.
    • match_all: the match all query. This query matches all documents and gives them all a boost value. The boost value is of the double type, and the default boost value is 1.0. Example: '{"query":{"match_all":{"boost":2.3}}}'.
    Note If you perform a compound query by using bool, dis_max, and constant_score, you can set boost values for term, terms, range, and wildcard. The default boost value is 1. You must specify the parameter to which the boost value is applied in the query syntax. Example: '{"query":{"bool":{"must":[{"match":{"f0":"v0"}},"term":{"f0":{"value":"redis","boost":2}}]}}}'.
  • sort: specifies to sort query results by a factor. Default value: _score. Valid values:
    • _score: sorts query results by weight in descending order. Example: "sort":"_score".
    • _doc: sorts query results by document ID in ascending order. Example: "sort":"_doc".
    • Specified field: sorts query results by specified field in ascending order. The field must be an indexed field (index set to true) or a field that is forcefully checked (enabled set to true). The field must be of the keyword, long, integer, or double type. For example, "sort":"price" specifies to sort query results by price in ascending order.
    You can also use an array to sort query results. In this case, query results are sorted by array order. You can use order to modify the default array order. Valid values of order: desc and acs. For example, '{"sort":[{"price":{"order":"desc"}},{"_doc":{"order":"desc"}}]}' specifies to sort query results by price or by document ID if the prices are the same.
  • _source: the fields displayed in query results. You can use includes to specify fields that you want to retain and use excludes to specify fields that you do not want to retain. Wildcards are accepted. For example, "_source":{"includes":["f0"] specifies to return only the f0 fields in query results.
  • aggs: specifies to aggregate results of the query clauses. For more information about the syntax and examples, see the "Aggregations" section of this topic.
  • track_total_hits: specifies whether to query all documents when you use the term, terms, or match query. In this case, compound query is supported. If you use the match query, fuzzy match is disabled. Valid values:
    • false: Only the top 100 documents are queried. Documents are sorted by score.
    • true: All documents are queried.
      Warning If track_total_hits is set to true and the number of documents to query is large, slow queries occur. Proceed with caution.
  • from: the start document to return. The default value is 0, which specifies to return the first document and all subsequent documents that are queried.
  • size: the number of documents that can be returned. Default value: 10. Valid values: 0 to 10000. A value of 0 specifies to return only the total number of obtained documents instead of specific documents.
    Note A combination of from and size works like paging. However, query performance degrades as the number of discrete pages increases.
Output
  • If the operation is successful, the documents in the index are returned.
    Note In the following sample output, relation indicates the number of returned documents. Valid values of relation: eq (equal to the value specified by value), gte (greater than or equal to the value specified by value).
    {
        "hits": {
            "hits": [],
            "max_score": null,
            "total": {
                "relation": "gte",
                "value": 100
            }
        }
    }
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.SEARCH idx:product '{"sort":[{"price":{"order":"desc"}}]}'

Sample output:

'{"hits":{"hits":[{"_id":"fruits_3","_index":"idx:product","_score":1.0,"_source":{"product_id":"fruits_3","product_name":"orange","price":30.2,"stock":3000}},{"_id":"fruits_2","_index":"idx:product","_score":1.0,"_source":{"product_id":"fruits_2","product_name":"banana","price":24.0,"stock":2000}},{"_id":"fruits_1","_index":"idx:product","_score":1.0,"_source":{"product_id":"fruits_1","product_name":"apple","price":19.5,"stock":1000}}],"max_score":1.0,"total":{"relation":"eq","value":3}}}'

TFT.MSEARCH

Item Description
Syntax TFT.MSEARCH index_count index [index1] ... query
Command description

Queries documents in multiple indexes that have mappings set to the same value by using the query clause and gathers the results from these indexes. Then, the results are rated, sorted, aggregated, and returned.

Note The output of the TFT.MSEARCH command is a result of rating, sorting, and aggregating query results from these indexes. The output is different from results generated by directly rating, sorting, and aggregating datasets in multiple indexes. TFT.MSEARCH policy:
  • Rate and sort: rates and sorts child result sets.
  • Aggregate:
    • sum, max, min, avg, or value_count: performs an aggregation operation on child result sets by using an aggregate function.
    • sum_of_squares, variance, or std_deviation: performs an averaging operation on child result sets.
    • terms aggregation or filter aggregation: performs another aggregation operation on child result sets.
Parameter
  • index_cout: the number of indexes that you want to query. Valid values: 1 to 100.
  • index: the names of the indexes that you want to query. These indexes must have mappings set to the same value.Otherwise, an error is reported.
  • query: the aggregation statement. The following parameters are supported:
    • query: the query clause.
    • sort: sorts the obtained results.
    • _source: specifies fields to return in the results.
    • aggs: aggregates the results of the query clause.
    • track_total_hits: specifies whether to query all documents when you use the term, terms, or match query. In this case, compound query is supported. If you use the match query, fuzzy match is disabled.
    • size: specifies the number of documents to return.

      Paged query can be implemented by using size, reply_with_keys_cursor, and keys_cursor. If keys_cursor is set to the default value 0, Tair retrieves a specified number of documents starting from the first document of the obtained results from the indexes. Otherwise, a specific number of documents are retrieved starting from a specific position. Then, the results from these indexes are gathered to be rated, sorted, aggregated, and returned as the output.

      For example, assume that you want to query three indexes key0, key1, and key2 at a time and that you set the size parameter to 10.
      • For the first query, set keys_cursor to 0. Tair retrieves the first 10 documents from these three indexes respectively. Then, Tair gathers, rates, sorts, and aggregates these 30 documents and returns the top 10 documents. Sample return value of keys_cursor: {"keys_cursor":{"key0":2,"key1":5,"key2":3}}.
      • For the second query, use the same query statement and add {"keys_cursor":{"key0":2,"key1":5,"key2":3}}. Tair retrieves the first 10 documents from the specified position in these indexes. For example, Tair retrieves 10 documents starting from the third one in the key0 index. Then, Tair gathers, rates, sorts, and aggregates the retrieved documents, and returns the output.
    • reply_with_keys_cursor: specifies whether to return the starting position of the next query for each index. Valid values: true and false. Default value: false.
    • keys_cursor: specifies the position of the cursor in each index for the query. To implement paged query, set keys_cursor to the return value for the last query. The default value is 0, which indicates that the query starts from the first document.
Note Unlike the query statement of the TFT.SEARCH command, the query statement of the TFT.MSEARCH command does not support the from parameter, but supports paged query by using the size, reply_with_keys_cursor, and keys_cursor parameters. For more information about the syntax of other parameters, see the "TFT.SEARCH" section of this topic.
Output
  • If the operation is successful, the obtained documents and aux_info are returned, which is the similar to the output of the TFT.SEARCH command.
    The aux_info field includes the CRC-64 value of the index mappingsand the value of keys_cursor. keys_cursor indicates the cursor position for the next query and is optional. For business requests, ignore the CRC-64 value. Example of aux_info:
    {
        "aux_info":{
            "index_crc64":15096806844241479487,
            "keys_cursor":{
                "key0":2,
                "key1":5,
                "key2":3
            }
        }
    }
  • Otherwise, an error message is returned.
Example
Run the following commands in advance:
TFT.CREATEINDEX key0 '{"mappings":{"properties":{"f0":{"type":"long"}}}}'
TFT.CREATEINDEX key1 '{"mappings":{"properties":{"f0":{"type":"long"}}}}'
TFT.CREATEINDEX key2 '{"mappings":{"properties":{"f0":{"type":"long"}}}}'
TFT.ADDDOC key0 '{"f0":120}'
TFT.ADDDOC key0 '{"f0":130}'
TFT.ADDDOC key1 '{"f0":140}'
TFT.ADDDOC key1 '{"f0":150}'
TFT.ADDDOC key2 '{"f0":160}'
TFT.ADDDOC key2 '{"f0":170}'

Sample command:

TFT.MSEARCH 3 key0 key1 key2 '{"size":2,"query":{"range":{"f0":{"gt":120,"lte":170}}},"sort":[{"f0":{"order":"desc"}}],"reply_with_keys_cursor":true}'

Sample output:

"{"hits":{"hits":[{"_id":"16625439765504840","_index":"key2","_score":1.0,"_source":{"f0":170}},{"_id":"16625439741096630","_index":"key2","_score":1.0,"_source":{"f0":160}}],"max_score":1.0,"total":{"relation":"eq","value":5}},"aux_info":{"index_crc64":10084399559244916810,"keys_cursor":{"key0":0,"key1":0,"key2":2}}}"

Sample command for querying the second page:

TFT.MSEARCH 3 key0 key1 key2 '{"size":2,"query":{"range":{"f0":{"gt":120,"lte":170}}},"sort":[{"f0":{"order":"desc"}}],"reply_with_keys_cursor":true,"keys_cursor":{"key0":0,"key1":0,"key2":2}}'
# Use the statement that you use in the first query and add the return value of keys_cursor for last query. 

Sample output:

"{"hits":{"hits":[{"_id":"16625439652681160","_index":"key1","_score":1.0,"_source":{"f0":150}},{"_id":"16625439624704580","_index":"key1","_score":1.0,"_source":{"f0":140}}],"max_score":1.0,"total":{"relation":"eq","value":5}},"aux_info":{"index_crc64":10084399559244916810,"keys_cursor":{"key0":0,"key1":2,"key2":2}}}"

TFT.ADDSUG

Item Description
Syntax TFT.ADDSUG index text weight [text weight] ...
Command description

Adds one or more auto-complete texts and their weights to the specified index.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • text: the auto-complete text that you want to add to the index.
  • weight: the weight of the text. The weight must be a positive integer.
Output
  • If the operation is successful, the number of added texts is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.ADDSUG idx:redis 'redis is a memory database' 3 'redis cluster' 10

Sample output:

(integer) 2

TFT.DELSUG

Item Description
Syntax TFT.DELSUG index text [text] ...
Command description

Deletes one or more auto-complete texts from the specified index.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • text: the text that you want to delete from the index. The text value must be complete and accurate.
Output
  • If the operation is successful, the number of deleted texts is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.DELSUG idx:redis 'redis is a memory database' 'redis cluster' 

Sample output:

(integer) 2

TFT.SUGNUM

Item Description
Syntax TFT.SUGNUM index
Command description

Obtains the number of auto-complete texts in the specified index.

Parameter
  • index: the name of the index that you want to manage by running this command.
Output
  • If the operation is successful, the number of texts in the index is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.SUGNUM idx:redis

Sample output:

(integer) 3

TFT.GETSUG

Item Description
Syntax TFT.GETSUG index prefix [MAX_COUNT count] [FUZZY]
Command description

Obtains the auto-complete texts that can be matched based on the specified prefix. Texts are returned in descending order of weights.

Parameter
  • index: the name of the index that you want to manage by running this command.
  • prefix: the prefix that you specify.
  • MAX_COUNT count: the maximum number of texts that can be returned. Valid values: 0 to 255.
  • FUZZY: specifies whether to enable fuzzy match.
Output
  • If the operation is successful, the number of texts in the index is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.GETSUG idx:redis res MAX_COUNT 2 FUZZY

Sample output:

1) "redis cluster"
2) "redis lock"

TFT.GETALLSUGS

Item Description
Syntax TFT.GETALLSUGS index
Command description

Obtains the full auto-complete texts in the specified index.

Parameter
  • index: the name of the index that you want to manage by running this command.
Output
  • If the operation is successful, a list of auto-complete texts is returned.
  • Otherwise, an error message is returned.
Example

Sample command:

TFT.GETALLSUGS idx:redis

Sample output:

1) "redis cluster"
2) "redis lock"
3) "redis is a memory database"

Aggregations

You can add the aggs (aggregations) parameter to TFT.SEARCH commands to aggregate results obtained by using query clauses.

Usage

In most cases, you must specify the aggregation name, type, and field for the aggs parameter. Only fields of the numeric and keyword types are supported. Sample command:
TFT.SEARCH shares '{"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Sum":{"sum":{"field":"purchase_price"}}}}'
# Specify Jay_Sum as the aggregation name, sum as the aggregation type, and purchase_price as the aggregation field. 
Query and aggregation results are returned. Example:
"{"hits":{"hits":[{"_id":"16581351808123930","_index":"today_shares0718","_score":1.0,"_source":{"shares_name":"XAX","logictime":14300210,"purchase_type":1,"purchase_price":101.1,"purchase_count":100,"investor":"Jay"}},{"_id":"16581351809626430","_index":"today_shares0718","_score":1.0,"_source":{"shares_name":"XAX","logictime":14300310,"purchase_type":1,"purchase_price":111.1,"purchase_count":100,"investor":"Jay"}}],"max_score":1.0,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Sum":{"value":212.2}}}"
Note You can add "size":0 to the query syntax so that only aggregation results are returned.

Aggregation types supported by aggs

Metric, terms, and filter aggregations are supported by the aggs parameter.
Item Description
Metric aggregation Computes metrics based on values extracted from the fields of documents that are being aggregated. These fields are typically of a numeric type, such as INTEGER or DOUBLE. Nested aggregations are not supported. Valid values:
  • sum: calculates the total value.
  • max: calculates the maximum value.
  • min: calculates the minimum value.
  • avg: calculates the average value.
  • sum_of_squares: calculates the sum of squares.
  • variance: calculates the variance.
  • std_deviation: calculates the standard deviation.
  • value_count: counts the number of values. Duplicated values are counted. Fields of numeric and keyword types are supported.
  • extended_stats: performs aggregations of all the preceding types and returns the results at once.
Note All parameters except for value_count only support numeric fields.
Output: DOUBLE-typed values obtained by using specific fields for calculation.
Terms aggregation Calculates the deduplicated number of values. Only fields of the keyword type are supported. Nested aggregations are supported. Valid values:
  • terms
    • field: the aggregation field. Only fields of the keyword type are supported.
    • size: the number of terms that can be returned. Default value: 10. Valid values: [1,65536).
    • order: the sort rule of returned terms. Default value: _count. Valid values:
      • _count: sorts terms by _count. This indicates that terms are sorted based on the number of documents associated with each term. Default value: desc. Valid values: desc and asc. Example: "order":{"_count":"desc"}.
      • _key: sorts results by _key. This indicates that terms are sorted in lexicographic order. Valid values: desc and asc. Example: "order":{"_key":"desc"}.
    • min_doc_count: the minimum number of documents that can be displayed. If the number of documents is less than the min_doc_count value, the number is not displayed.
    • include: the string to be contained or matched. If the field is a string, regular expression match is supported. If the field is an array, exact match is required.
    • exclude: the string that cannot be contained or matched. The field types supported are the same as those supported by include. If both include and exclude are specified, include takes precedence over exclude.
Example:
{
  "aggs": {
    "Per_Investor_Freq":{
      "terms": {
        "field": "investor"
      }
    }
  }
}
Output: a JSON object obtained by using the key aggregation. In the object, the key aggregation uses buckets to display statistics. Each bucket contains a key (aggregation field) and a doc_count (number of documents associated with the aggregation field). The following code provides an example:
{
  "aggregations": {
    "Per_Investor_Freq": {
      "buckets": [
        {
          "doc_count": 2,
          "key": "Jay"
        },
        {
          "doc_count": 1,
          "key": "Mila"
        }
      ]
    }
  }
 }
Filter aggregation Filters query results of a query statement. Nested aggregations are supported.

Output: the number of documents (doc_count) that match the filter conditions.

Aggregation examples

  1. Create an index.
    TFT.CREATEINDEX today_shares '{"mappings":{"properties":{"shares_name":{"type":"keyword"},"logictime":{"type":"long"},"purchase_type":{"type":"integer"},"purchase_price":{"type":"double"},"purchase_count":{"type":"long"},"investor":{"type":"keyword"}}}}'
    # Create an index that represents the stock trading volume of today.
    # shares_name: the name of each stock
    # logictime: the time when the dealing is complete
    # purchase_type: the purchase type
    # purchase_price: the purchase price
    # purchase_count: the number of purchased stock shares
    # investor: the ID of the buyer

    Expected output:

    OK
  2. Add document data.
    Run the following commands:
    TFT.ADDDOC today_shares '{"shares_name":"XAX","logictime":14300210, "purchase_type":1,"purchase_price":101.1, "purchase_count":100,"investor":"Jay"}';
    TFT.ADDDOC today_shares '{"shares_name":"XAX","logictime":14300310, "purchase_type":1,"purchase_price":111.1, "purchase_count":100,"investor":"Jay"}';
    TFT.ADDDOC today_shares '{"shares_name":"YBY","logictime":14300410, "purchase_type":1,"purchase_price":11.1, "purchase_count":100,"investor":"Mila"}';

    Expected output:

    OK
  3. Perform a query.
    Sample commands:
    # Query the total amount that Jay spent to purchase the stocks. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Sum":{"sum":{"field":"purchase_price"}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Sum":{"value":212.2}}}"
    # Query the largest amount that Jay spent to purchase a stock. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Max":{"max":{"field":"purchase_price"}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Max":{"value":111.1}}}"
    # Query the average amount that Jay spent to purchase different stocks. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Avg":{"avg":{"field":"purchase_price"}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Avg":{"value":106.1}}}"
    # Query the standard deviation of the amount that Jay spent to purchase stocks. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Std_Deviation":{"std_deviation":{"field":"purchase_price"}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Std_Deviation":{"value":5.0}}}"
    # Query the statistics of the amount that Jay spent to purchase stocks. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Extended_Stats":{"extended_stats":{"field":"purchase_price"}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Extended_Stats":{"count":2,"sum":212.2,"max":111.1,"min":101.1,"avg":106.1,"sum_of_squares":10221.21,"variance":25.0,"std_deviation":5.0}}}"
    # Query the buyers that have completed at least two transactions. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"purchase_type":1}},"aggs":{"Per_Investor_Freq":{"terms":{"field":"investor","min_doc_count":2,"order": {"_key":"desc"}}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":3}},"aggregations":{"Per_Investor_Freq":{"buckets":[{"key":"Jay","doc_count":2}]}}}"
    # Query the number of transactions conducted for each stock and the average amount spent to purchase each stock. The XAX stock is excluded. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"purchase_type":1}},"aggs":{"Per_Investor_Freq":{"terms":{"field":"shares_name","include":"[A-Z]+","exclude":["XAX"]},"aggs":{"Price_Avg":{"avg":{"field":"purchase_price"}}}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":3}},"aggregations":{"Per_Investor_Freq":{"buckets":[{"key":"YBY","doc_count":1,"Price_Avg":{"value":11.1}}]}}}"
    # Query the total number of stocks purchased by Jay and the statistics of the amount that Jay spent to purchase stocks. 
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"purchase_type":1}}, "aggs":{"Jay_BuyIn_Filter": {"filter": {"term":{"investor": "Jay"}},"aggs":{"Jay_BuyIn_Quatation":{"extended_stats":{"field":"purchase_price"}}}}}}'
    
    # Expected output:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":3}},"aggregations":{"Jay_BuyIn_Filter":{"doc_count":2,"Jay_BuyIn_Quatation":{"count":2,"sum":212.2,"max":111.1,"min":101.1,"avg":106.1,"sum_of_squares":10221.21,"variance":25.0,"std_deviation":5.0}}}}"