TairSearch是基于Redis module全自研(不基于Lucene等开源搜索库)的全文搜索数据结构,采用和Elasticsearch相似(ES-LIKE)的查询语法。

TairSearch简介

与Elasticsearch相比,TairSearch具有如下主要特点:
  • 低延迟、高性能:依托Tair的超高性能计算能力,提供毫秒级别的写入和全文搜索能力。
  • 增量、局部更新:支持文档的增量更新与局部索引更新,包括追加字段、更新字段、删除字段以及字段自增等。
  • 语法灵活:支持更加灵活、可读性更强的JSON查询语法,提供Bool、Match、Term、分页等查询功能,语法与Elasticsearch类似,同时支持自定义排序。
  • 聚合查询:支持Terms、Metrics、Filter等聚合算子,更多信息请参见Aggregations介绍
  • Auto-complete Suggestion:支持前缀模糊搜索、自动补全等功能。
  • 分词定制:内置中文、英文及世界主要语言分词器,同时提供灵活的分词器定制能力,可自由定制分词器。
发布记录
  1. 2022年03月11日发布1.7.27版本,首次发布TairSearch。
  2. 2022年05月24日发布1.8.5版本,支持TairSearch Aggregations(聚合)功能。
  3. 2022年09月06日发布5.0.15版本,支持TFT.MSEARCH功能。

最佳实践

前提条件

实例为Tair(Redis企业版)内存型,且小版本为1.7.27及以上。
说明 最新小版本将提供更丰富的功能与稳定的服务,建议将实例的小版本升级到最新,具体操作请参见升级小版本。若实例为集群架构读写分离架构,请将代理节点的小版本也升级到最新,避免代理节点无法识别部分命令。

注意事项

  • 操作对象为Tair实例中的TairSearch数据。
  • 为节省内存,推荐使用如下方法:
    • 创建索引(index)时请将文档中需要创建(反向)索引的字段设置为索引字段(将字段的index设置为true),其余字段的index设置为false。
    • 使用_source参数中的include与exclude机制剔除源文档中不需要的字段(field),保存需要的信息。
  • 避免在单个索引中插入过多的文档,推荐将文档存入多个不同的索引中,建议单个索引的文档数在500万以下,可有效规避(集群)实例发生数据倾斜,均衡读写流量,避免造成大Key与热key。

命令列表

表 1. 全文检索命令
命令 语法 说明
TFT.CREATEINDEX TFT.CREATEINDEX index mappings

创建索引(index)并添加映射(mappings),映射语法类似ES语法。在添加索引文档前,必须先创建索引。

TFT.UPDATEINDEX TFT.UPDATEINDEX index mappings

向指定的索引中新增properties字段,不能与原有字段冲突,否则会新增失败。

TFT.GETINDEX TFT.GETINDEX index

获取索引的映射内容。

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

向索引中插入一个文档(document),可通过WITH_ID指定该文档在索引内的唯一ID(doc_id),若doc_id已存在,则更新并覆盖原文档。若不指定WITH_ID(默认),则自动生成doc_id。

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

向索引中插入多个文档(document),每个文档必须指定文档ID(doc_id)。

TFT.UPDATEDOCFIELD TFT.UPDATEDOCFIELD index doc_id document
更新索引中doc_id指定的文档,若更新的字段为mapping指定的索引字段时,该字段更新的内容需与mapping指定的类型一致;若非索引字段,支持更新任意字段类型的内容。
说明 若更新的字段已存在,则更新原文档,若字段不存在,则新增该字段。若指定的文档不存在,该命令支持自动创建文档,此时效果等同于TFT.ADDDOC。
TFT.DELDOCFIELD TFT.DELDOCFIELD index doc_id field [field1 field2 ...]
删除索引中doc_id指定文档的指定字段,若该字段为索引字段,会同时在索引中删除该字段的信息。
说明 若指定的字段不存在(例如被_source过滤的字段),则操作失败。
TFT.INCRLONGDOCFIELD TFT.INCRLONGDOCFIELD index doc_id field increment
向索引中doc_id指定文档的指定字段增加整数值(increment),支持指定increment为负数,支持指定的字段类型为long或int类型。
说明 若指定的文档不存在,该命令支持自动创建文档,初始化字段的值为0,并增加指定的increment。若指定的字段不存在(例如被_source过滤的字段),则操作失败。
TFT.INCRFLOATDOCFIELD TFT.INCRFLOATDOCFIELD index doc_id field increment
向索引中doc_id指定文档的指定字段增加浮点数值(increment),支持指定increment为负数,支持指定的字段类型为int、long或double类型。
说明 若指定的文档不存在,该命令支持自动创建文档,初始化字段的值为0,并增加指定的increment。若指定的字段不存在(例如被_source过滤的字段),则操作失败。
TFT.GETDOC TFT.GETDOC index doc_id

获取索引中指定doc_id的文档内容。

TFT.EXISTS TFT.EXISTS index doc_id

查询索引中指定doc_id的文档是否存在。

TFT.DOCNUM TFT.DOCNUM index

获取索引中的文档数量。

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

获取索引中所有的doc_id。

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

删除索引中doc_id指定的文档,支持指定多个doc_id。

TFT.DELALL TFT.DELALL index

删除索引中所有文档,但不会删除索引。

TFT.SEARCH TFT.SEARCH index query

根据query语句搜索索引的文档,query语法类似ES语法

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

根据query语句搜索多个索引的文档(待查询索引的mappings配置必须相同),汇聚多个索引的查询结果,再次进行打分、排序、聚合并返回。

DEL DEL key [key ...] 使用原生Redis的DEL命令可以删除一条或多条TairSearch数据。
表 2. 自动补齐命令
命令 语法 说明
TFT.ADDSUG TFT.ADDSUG index text weight [text weight] ...

在指定索引中,添加自动补全的文本及对应权重,支持添加多个文本。

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

在指定索引中,删除自动补全的文本,支持删除多个文本。

TFT.SUGNUM TFT.SUGNUM index

获取指定索引中自动补全文本的数量。

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

根据指定前缀,查询匹配的自动补全文本,将优先返回权重比较高的text。

TFT.GETALLSUGS TFT.GETALLSUGS index

获取指定索引的全量自动补全文本。

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

TFT.CREATEINDEX

类别 说明
语法 TFT.CREATEINDEX index mappings
命令描述

创建索引(index)并添加映射(mappings),映射语法类似ES语法。在添加索引文档前,必须先创建索引。

说明 为避免产生大Key,您可以预先将大索引拆分成小索引,并设计负载规则将数据写入不同的索引中。创建该类索引时,必须使该类索引具备相同的mappings配置,创建后可通过TFT.MSEARCH进行查询。
选项
  • index:待创建的索引名称。
  • mappings:映射内容,支持的语法如下。
    • dynamic:映射模式,支持strict(严格映射),表示仅能写入在properties中已设置过的字段,无法成功写入未配置过的字段。若未指定该参数,则默认为非严格映射模式,即不会检查写入的字段是否已在properties中设置。
    • enabled:强制检查写入文档的字段类型与properties中指定的类型是否一致,若不一致则写入失败,取值为true(默认,表示会检查)和false。该参数仅对非索引字段(index为false)生效,索引字段会强制检查字段类型。
    • _source:设置存储原始文档,该参数不会影响对应字段索引的创建,取值如下。
      enabled:是否存储原始文档,取值如下。
      • true(默认):存储原始文档,默认存储所有字段。

        可指定excludes(不需要存储的字段)和includes(需要存储的字段),支持配置通配符模式(WildCard)的字段。若某字段同时出现在excludesincludes时,则excludes的优先级大于includes,表示该字段最终不会存储在原始文档中,示例如下。

        示例一:"_source":{"enabled":true}(默认),表示存储所有字段,等同于"_source":{"enabled":true,"excludes":[],"includes":[]}

        示例二:"_source":{"enabled":true,"excludes":[],"includes":["id","name"]},表示仅存储“id”、“name”字段。

      • false:不存储原始文档。
    • properties:映射的字段集合,每个字段可设置如下属性。
      • index:是否将该字段设置为索引字段,取值如下:
        • true(默认):索引字段,查询时仅能通过索引字段查找文档。

          Tair会在内存中存储所有索引字段的原始文档,若该字段在_source中配置不存储原始文档,则在查询时返回的原始文档中不显示该字段。

        • false:非索引字段。
      • boost:该字段的计分权重,默认为1,范围为正浮点数,Tair将自动计算出各个字段的相对计算分。
      • type:字段的数据类型,取值如下。
        • keyword:不可被拆分字符串。可指定如下参数:
          • ignore_above:指定keyword的字符串长度上限,默认为128,例如"ignore_above":128
        • text:字符串,且可通过分词器解析,存入索引。可指定如下参数:
          • analyzer:解析text存入索引的分词器,支持standard(默认,英文分词器)、chinesearabiccjkczechbraziliangermangreekpersianfrenchdutchrussianjieba(推荐的中文分词,效果比chinese好)。例如"analyzer":"jieba",表示使用中文分词器。
          • search_analyzer:指定搜索时使用的分词器,支持的分词器类型与analyzer相同,默认为analyzer的设置。
        • long:长整型,您可以将时间点转为Unix时间戳,存入该数据类型中。
        • integer:整型。
        • double:双精度浮点型。
返回值
  • 执行成功:返回OK。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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"}}}}'

# 创建商品ID(product_id)为keyword数据类型,并设置上限为128个字符。
# 创建商品名称(product_name)为text数据类型。
# 创建商品标题(product_title)为text数据类型,并设置分词器为中文。
# 创建价格(price)为double数据类型。

返回示例:

OK

TFT.UPDATEINDEX

类别 说明
语法 TFT.UPDATEINDEX index mappings
命令描述

向指定的索引中新增properties字段,不能与原有字段冲突,否则会新增失败。

选项
  • index:待操作的索引名称。
  • mappings:映射内容,无需输入dynamic_source等信息,仅输入新增的properties字段。
说明 mappings的语法请参见TFT.CREATEINDEX
返回值
  • 执行成功:返回OK。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

OK

TFT.GETINDEX

类别 说明
语法 TFT.GETINDEX index
命令描述

获取索引的映射内容。

选项
  • index:待操作的索引名称。
返回值
  • 执行成功:返回索引的映射内容,格式为JSON。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.GETINDEX idx:product

返回示例:

{"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

类别 说明
语法 TFT.ADDDOC index document [WITH_ID doc_id]
命令描述

向索引中插入一个文档(document),可通过WITH_ID指定该文档在索引内的唯一ID(doc_id),若doc_id已存在,则更新并覆盖原文档。若不指定WITH_ID(默认),则自动生成doc_id。

选项
  • index:待操作的索引名称。
  • document:插入的文档,JSON格式。
    说明 若index通过_sourceincludes参数配置了仅保存部分字段,则在插入或更新文档时仅保存includes中配置的字段。
  • WITH_ID doc_id:是否指定文档ID,如需指定文档ID需输入doc_id值,doc_id的格式为任意字符串。
返回值
  • 执行成功:返回文档ID,格式为JSON。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

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

TFT.MADDDOC

类别 说明
语法 TFT.MADDDOC index document doc_id [document1 doc_id1] ...
命令描述

向索引中插入多个文档(document),每个文档必须指定文档ID(doc_id)。

选项
  • index:待操作的索引名称。
  • document:插入的文档,JSON格式。
    说明 若index通过_sourceincludes参数配置了仅保存部分字段,则在插入或更新文档时仅保存includes中配置的字段。
  • doc_id:指定文档ID,doc_id的格式为任意字符串。
返回值
  • 执行成功:返回OK。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

OK

TFT.UPDATEDOCFIELD

类别 说明
语法 TFT.UPDATEDOCFIELD index doc_id document
命令描述
更新索引中doc_id指定的文档,若更新的字段为mapping指定的索引字段时,该字段更新的内容需与mapping指定的类型一致;若非索引字段,支持更新任意字段类型的内容。
说明 若更新的字段已存在,则更新原文档,若字段不存在,则新增该字段。若指定的文档不存在,该命令支持自动创建文档,此时效果等同于TFT.ADDDOC。
选项
  • index:待操作的索引名称。
  • doc_id:指定文档ID。
  • document:更新的文档内容,JSON格式。
    说明 若index通过_sourceincludes参数配置了仅保存部分字段,则在插入或更新文档时仅保存includes中配置的字段。
返回值
  • 执行成功:返回OK。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

OK

TFT.DELDOCFIELD

类别 说明
语法 TFT.DELDOCFIELD index doc_id field [field1 field2 ...]
命令描述
删除索引中doc_id指定文档的指定字段,若该字段为索引字段,会同时在索引中删除该字段的信息。
说明 若指定的字段不存在(例如被_source过滤的字段),则操作失败。
选项
  • index:待操作的索引名称。
  • doc_id:指定文档ID。
  • field:待删除的字段。
返回值
  • 执行成功:返回成功删除的字段数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.DELDOCFIELD idx:product 00011 product_group

返回示例:

(integer) 1

TFT.INCRLONGDOCFIELD

类别 说明
语法 TFT.INCRLONGDOCFIELD index doc_id field increment
命令描述
向索引中doc_id指定文档的指定字段增加整数值(increment),支持指定increment为负数,支持指定的字段类型为long或int类型。
说明 若指定的文档不存在,该命令支持自动创建文档,初始化字段的值为0,并增加指定的increment。若指定的字段不存在(例如被_source过滤的字段),则操作失败。
选项
  • index:待操作的索引名称。
  • doc_id:指定文档ID。
  • field:待操作的字段,支持的字段类型为long或int类型。
  • increment:待增加操作的值,可以指定该值为负数实现相减,数据类型为整型(int)。
返回值
  • 执行成功:返回执行操作后字段的数值。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.INCRLONGDOCFIELD idx:product 00011 stock 100

返回示例:

(integer)100

TFT.INCRFLOATDOCFIELD

类别 说明
语法 TFT.INCRFLOATDOCFIELD index doc_id field increment
命令描述
向索引中doc_id指定文档的指定字段增加浮点数值(increment),支持指定increment为负数,支持指定的字段类型为int、long或double类型。
说明 若指定的文档不存在,该命令支持自动创建文档,初始化字段的值为0,并增加指定的increment。若指定的字段不存在(例如被_source过滤的字段),则操作失败。
选项
  • index:待操作的索引名称。
  • doc_id:指定文档ID。
  • field:待操作的字段,支持的字段类型为long、int或double类型。
  • increment:待增加操作的值,可以指定该值为负数实现相减,数据类型为双精度浮点型(double)。
返回值
  • 执行成功:返回执行操作后字段的数值。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.INCRFLOATDOCFIELD idx:product 00011 stock 299.6

返回示例:

"299.6"

TFT.GETDOC

类别 说明
语法 TFT.GETDOC index doc_id
命令描述

获取索引中指定doc_id的文档内容。

选项
  • index:待查询的索引名称。
  • doc_id:指定文档ID。
返回值
  • 执行成功:返回文档ID和文档内容。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.GETDOC idx:product 00011

返回示例:

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

TFT.EXISTS

类别 说明
语法 TFT.EXISTS index doc_id
命令描述

查询索引中指定doc_id的文档是否存在。

选项
  • index:待查询的索引名称。
  • doc_id:指定文档ID。
返回值
  • 执行成功:
    • 若文档存在,返回1。
    • 若索引或文档不存在,返回0。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.EXISTS idx:product 00011

返回示例:

(integer) 1

TFT.DOCNUM

类别 说明
语法 TFT.DOCNUM index
命令描述

获取索引中的文档数量。

选项
  • index:待查询的索引名称。
返回值
  • 执行成功:索引的文档数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.DOCNUM idx:product

返回示例:

(integer) 3

TFT.SCANDOCID

类别 说明
语法 TFT.SCANDOCID index cursor [MATCH *value*] [COUNT count]
命令描述

获取索引中所有的doc_id。

选项
  • index:待查询的索引名称。
  • cursor:指定本次扫描的游标。
  • MATCH *value*:模式匹配,value为待匹配的值,例如MATCH *redis*
  • COUNT count:指定本次扫描的最大数量,默认为100。
返回值
  • 执行成功:返回一个数组。
    • 第一个元素:下次查询的cursor,若该key已扫描完成,则返回0。
    • 第二个元素:本次查询的doc_id。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.SCANDOCID idx:product 0 COUNT 3

返回示例:

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

TFT.DELDOC

类别 说明
语法 TFT.DELDOC index doc_id [doc_id] ...
命令描述

删除索引中doc_id指定的文档,支持指定多个doc_id。

选项
  • index:待查询的索引名称。
  • doc_id:指定文档ID。
返回值
  • 执行成功:返回成功删除的文档数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.DELDOC idx:product 00011 00014

返回示例:

"1"    # 本示例中ID"00014"文档不存在,故仅删除ID"00011"文档,返回1。

TFT.DELALL

类别 说明
语法 TFT.DELALL index
命令描述

删除索引中所有文档,但不会删除索引。

选项
  • index:待查询的索引名称。
  • doc_id:指定文档ID。
返回值
  • 执行成功:返回OK。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.DELALL idx:product

返回示例:

OK

TFT.SEARCH

类别 说明
语法 TFT.SEARCH index query
命令描述

根据query语句搜索索引的文档,query语法类似ES语法

选项

index为待查询的索引名称;query为类似ES语法的DLS语句,支持如下字段:

  • query:查询子句,支持如下语法。
    • match:基础的匹配查询,支持如下参数。

      在不需要对文档进行分词拆分或模糊匹配的场景下,推荐使用termprefix等命令,以提高查询效率。

      • query:查询的文档内容。
        说明
        • 未开启模糊匹配(fuzziness)时,query中的文档会被指定分词器(analyzer)拆分成多个词根,同时您可以指定operator(不同词根之间的关系)、minimum_should_match(至少需要匹配多少个词根)参数。
        • 开启了模糊匹配(fuzziness)时,上述参数将无效,您可以指定prefix_length参数。
      • analyzer:指定match查询语句的分词器,支持standard(默认,英文分词器)、chinesearabiccjkczechbraziliangermangreekpersianfrenchdutchrussianjieba(中分分词)。
      • minimum_should_match:查询语句会通过分词器拆分成多个词根,您可以通过本参数指定至少需要匹配多少个词根。该参数在未开启模糊匹配且operator为OR时生效。
      • operator:指定通过分词器拆分的词根之间的关系,取值为AND和OR(默认)。例如'{"query":{"match":{"f0":{"query":"redis cluster","operator":"OR"}}}}',表示待搜索的文档中包含"redis"或"cluster"即满足查询条件。
      • fuzziness:是否开启模糊匹配查询,默认为关闭,"fuzziness":1为开启模糊匹配,例如'{"query":{"match":{"f0":{"query":"excelentl","fuzziness":1}}}}'
      • prefix_length:设置模糊匹配保持不变的起始字符数,默认为0,该参数仅在开启模糊匹配时生效。
    • term:词根查询,不会对查询内容进行拆分,效率比match高,支持查询所有字段类型。例如'{"query":{"term":{"f0":{"value":"redis","boost": 2.0}}}}''{"query":{"term":{"f0":"redis"}}}'
    • terms:多词根查询,上限为1024个词根。例如'{"query":{"terms":{"f0":["redis","excellent"]}}}'
    • range:范围查询,支持所有字段类型,取值为lt(小于)、gt(大于)、lte(小于等于)和gte(大于等于),例如'{"query":{"range":{"f0":{"lt":"abcd","gt":"ab"}}}}'
    • wildcard:通配符查询,格式为"wildcard":{"待查询field":{"value":"查询内容"}},只支持*?通配符,例如'{"query":{"wildcard":{"f0":{"value":"*b?Se"}}}}'
    • prefix:前缀查询,例如'{"query":{"prefix":{"f0":"abcd"}}',表示查询f0字段以abcd为开头的文档。
    • bool:复合查询,上限为1024个词根,取值如下。
      • must:查询结果需匹配must列表中所有查询子句,例如'{"query":{"bool":{"must":[{"match":{"DB":"redis"}},{"match":{"Architectures":"cluster"}}]}}}',表示查询DB为Redis、架构(Architectures)为cluster的文档。
      • must_not:查询结果需不匹配must_not列表中所有查询子句。
      • should:查询结果需匹配should列表中任意一个查询子句(表示或),可指定minimum_should_match参数。
      • minimum_should_match:该参数需搭配should语句使用,表示至少需匹配多少个查询子句。若bool语句中只有should语句,则该参数默认为1;bool语句中还有mustmust_not语句,则该参数默认为0。例如'{"query":{"bool":{"minimum_should_match":1,"should":[{"match":{"DB":"redis"}},{"match":{"Architectures":"cluster"}}]}}}',表示查询DB为Redis或架构(Architectures)为cluster的文档。
      说明 bool查询语句中可嵌套任何类型的子查询语句,例如嵌套bool语句,示例为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:最佳匹配复合查询,默认返回queries查询子句中单个query分数最高的结果在首位。

      若指定了tie_breaker参数,将增加匹配多个查询子句的文档分数,tie_breaker的取值范围为[0,1],默认为0。指定tie_breaker后,目标文档分数的计算规则为:query的最高分+((将除最高分以外的query分数相加) * tie_breaker)。例如查询中有3个子句,tie_breaker为0.5,doc1在每个子句的分数为[5,1,3],最终doc1分数为5+((1+3)*0.5)。

      命令示例为'{"query":{"dis_max":{"queries":[{"term":{"f0":"redis"}},{"term":{"f1":"database"}},{"match":{"title":"redis memory database"}}],"tie_breaker": 0.5}}}'

    • constant_score:固定分数的复合查询,通过filter查询并返回任意一个符合的文档,支持设置权重(boost,double类型,默认为1.0),文档将以指定的boost返回。例如'{"query":{"constant_score":{"filter":{"term":{"f0":"abc"}},"boost":1.2}}}'
    • match_all:查询全部文档,支持设置权重(boost,double类型,默认为1.0),可以将指定的分数赋予所有返回的文档,例如'{"query":{"match_all":{"boost":2.3}}}'
    说明 通过booldis_maxconstant_score进行复合查询时,可对termtermsrangewildcard设置权重(boost,默认为1),区分多个条件的权重,例如'{"query":{"bool":{"must":[{"match":{"f0":"v0"}},"term":{"f0":{"value":"redis","boost":2}}]}}}'
  • sort:结果排序,取值如下。
    • _score(默认):按计分权重降序,示例为"sort":"_score"
    • _doc:按文档ID升序,示例为"sort":"_doc"
    • 指定字段:按指定字段升序,该字段必须为索引(index为true)字段或开启强制类型检查(enabled为true)的字段,同时仅支持指定字段类型为:keyword、long、integer、double。例如"sort":"price",表示指定以price字段升序排序。
    支持输入一个数组进行多条件排序,将按照数组内的顺序进行排序,可通过order调整默认顺序,取值为desc(降序)和acs(升序)。例如'{"sort":[{"price":{"order":"desc"}},{"_doc":{"order":"desc"}}]}',表示优先根据price排序,在price相同时根据_doc排序。
  • _source:指定查询结果中的字段,可指定includes(需要展示的field)和excludes(不需要展示的field),支持配置通配符模式(WildCard)的field。例如"_source":{"includes":["f0"],表示查询结果仅返回f0字段。
  • aggs:对query查询子句的结果进行聚合,语法与示例请参见Aggregations介绍
  • track_total_hits:通过termtermsmatch(不开启模糊匹配)语句查询(含复合查询)时,是否查询所有文档。取值如下:
    • false(默认):仅查询score排名前100的文档。
    • true:查询所有文档。
      警告 开启后,若命中的文档数过多会导致慢查询,请谨慎使用。
  • from:指定开始返回的目标文档起点,默认为0,表示从第一个查到的文档开始返回。
  • size:返回查询的文档数量,默认为10,取值范围为[0,10000]。size为0表示结果集中不返回具体的文档, 只返回命中查询的总文档数量(total)。
    说明 可通过fromsize参数到达分页的效果,但分页越多越影响性能。
返回值
  • 执行成功:返回查询到的文档信息。
    说明 返回参数中的relation为查询到的文档数量,取值:eq(表示查询到的文档数量等于value值)、gte(表示大于或等于value值),示例如下。
    {
        "hits": {
            "hits": [],
            "max_score": null,
            "total": {
                "relation": "gte",
                "value": 100
            }
        }
    }
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

'{"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

类别 说明
语法 TFT.MSEARCH index_count index [index1] ... query
命令描述

根据query语句搜索多个索引的文档(待查询索引的mappings配置必须相同),汇聚多个索引的查询结果,再次进行打分、排序、聚合并返回。

说明 TFT.MSEARCH命令返回的结果是对多个索引的查询结果再次进行打分、排序、聚合的结果,该结果不等同于对多个索引的数据集合直接进行打分、排序、聚合等结果。TFT.MSEARCH的策略如下:
  • 打分和排序:对子结果集再进行打分、排序。
  • 聚合:
    • Sum、max、min、avg、value_count:对子结果集再进行同等属性的聚合运算。
    • Sum_of_squares、variance、std_deviation:对子结果集进行取均值运算。
    • Terms Aggregation和Filter Aggregation:对子结果集再进行统计聚合运算。
选项
  • index_cout:待查询的索引数量,取值范围为[1,100]。
  • index:待查询的索引名称。查询多个索引时,待查询索引的mappings配置必须相同,若各索引的mappings配置不一致或索引不存在均会报错。
  • query:聚合查询语句,支持如下参数:
    • query:查询子句。
    • sort:结果排序。
    • _source:指定查询结果中的字段。
    • aggs:对query查询子句的结果进行聚合。
    • track_total_hits:通过term、terms、match(不开启模糊匹配)语句查询(含复合查询)时,是否查询所有文档。
    • size:指定查询返回的文档数量。

      可通过sizereply_with_keys_cursorkeys_cursor参数实现分页查询。若keys_cursor为0(默认情况下),Tair会在各索引的查询结果中,从排序最高的文档(第一位)开始,获取指定数量的文档;若keys_cursor不为0,则从指定位置开始获取指定数量的文档,再将多个索引的查询结果汇聚在一起,进行打分、排序、聚合,并输出最终文档。

      例如单次查询3个索引(key0、key1、key2),设置size为10:
      • 首次搜索,可设置keys_cursor为0:Tair会从3个索引中各搜索出排序靠前的10个文档(此时共有30个候选文档),然后汇聚、打分、排序、聚合等,输出整体排名靠前的10个文档。返回的keys_cursor示例为{"keys_cursor":{"key0":2,"key1":5,"key2":3}}
      • 第二次查询时,可使用同样的查询语句,并加上{"keys_cursor":{"key0":2,"key1":5,"key2":3}}Tair会在各个索引中,从指定的位置开始再获取10个文档(例如key0从第3位开始向后获取10个文档,key1与key2也类似,此时仍有30个候选文档),再将多个索引的查询结果汇聚在一起,进行打分、排序、聚合,并输出最终文档。
    • reply_with_keys_cursor:指定是否返回每个索引下一轮查询的游标信息,取值:true、false(默认)。
    • keys_cursor:指定本次查询的各索引的游标,可以将上轮查询返回的keys_cursor作为本次查询的输入,实现分页查询。默认为0,表示第一位。
说明 相比较TFT.SEARCH的query语句,TFT.MSEARCH的query不支持from参数,但可以通过sizereply_with_keys_cursorkeys_cursor参数实现分页查询,其余参数语法均可参见TFT.SEARCH
返回值
  • 执行成功:返回查询到的文档信息,与TFT.SEARCH的返回结果类似,同时还会返回aux_info
    aux_info字段中包含:索引mappings的CRC-64值(业务请求可忽略该值)、keys_cursor值(可选,下次各索引开始查询的游标位置),aux_info示例如下:
    {
        "aux_info":{
            "index_crc64":15096806844241479487,
            "keys_cursor":{
                "key0":2,
                "key1":5,
                "key2":3
            }
        }
    }
  • 其他情况返回相应的异常信息。
示例
提前执行如下命令:
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}'

命令示例:

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

返回示例:

"{"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}}}"

第二页查询命令示例:

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}}'
# 查询语句与第一次查询相同,但需要增加上轮查询返回的keys_cursor信息。

返回示例:

"{"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

类别 说明
语法 TFT.ADDSUG index text weight [text weight] ...
命令描述

在指定索引中,添加自动补全的文本及对应权重,支持添加多个文本。

选项
  • index:待操作的索引名称。
  • text:自动补全文本。
  • weight:对应文本的计分权重,范围为正整数。
返回值
  • 执行成功:返回成功添加的文档数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

(integer) 2

TFT.DELSUG

类别 说明
语法 TFT.DELSUG index text [text] ...
命令描述

在指定索引中,删除自动补全的文本,支持删除多个文本。

选项
  • index:待查询的索引名称。
  • text:待删除的文本,需指定完整、正确的文本。
返回值
  • 执行成功:返回成功删除的文本数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

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

返回示例:

(integer) 2

TFT.SUGNUM

类别 说明
语法 TFT.SUGNUM index
命令描述

获取指定索引中自动补全文本的数量。

选项
  • index:待查询的索引名称。
返回值
  • 执行成功:返回索引中的文本数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.SUGNUM idx:redis

返回示例:

(integer) 3

TFT.GETSUG

类别 说明
语法 TFT.GETSUG index prefix [MAX_COUNT count] [FUZZY]
命令描述

根据指定前缀,查询匹配的自动补全文本,将优先返回权重比较高的text。

选项
  • index:待查询的索引名称。
  • prefix:指定的查询前缀。
  • MAX_COUNT count:配置返回文本的最大数量,count的取值范围为[0,255]。
  • FUZZY:是否启用模糊匹配。
返回值
  • 执行成功:返回索引中的文本数量。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.GETSUG idx:redis res MAX_COUNT 2 FUZZY

返回示例:

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

TFT.GETALLSUGS

类别 说明
语法 TFT.GETALLSUGS index
命令描述

获取指定索引的全量自动补全文本。

选项
  • index:待查询的索引名称。
返回值
  • 执行成功:返回自动补全文本的列表。
  • 其他情况返回相应的异常信息。
示例

命令示例:

TFT.GETALLSUGS idx:redis

返回示例:

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

Aggregations介绍

您可以在TFT.SEARCH请求中添加aggs(或aggregations)子句,对query查询子句的结果进行聚合。

用法

通常情况下,在aggs子句中,您需要自定义聚合名称,并指定聚合类型与聚合字段(field),仅支持聚合数值类型与keyword类型的字段,例如:
TFT.SEARCH shares '{"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Sum":{"sum":{"field":"purchase_price"}}}}'
# 自定义聚合名称为Jay_Sum、聚合类型为sum(求和)、聚合字段为purchase_price。
返回结果包含query的查询结果和aggs的聚合结果:
"{"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}}}"
说明 您可以在查询语句中加上"size":0,将仅返回aggs的结果。

aggs聚合类型

aggs支持Metric Aggregation、Terms Aggregation、Filter Aggregation功能。
类别 说明
Metric(指标) Aggregation 一般是对数值类型(例如integer、double等)字段进行数值计算或统计,不支持嵌套子聚合。支持如下指标:
  • sum:求和。
  • max:最大值。
  • min:最小值。
  • avg:平均值。
  • sum_of_squares:平方和。
  • variance:方差。
  • std_deviation:标准差。
  • value_count:统计value个数,不进行去重,支持数值类型与keyword类型字段。
  • extended_stats:进行上述所有指标的计算,一次性返回各类结果。
说明value_count外,其余指标均只支持数值类型字段。
返回结果:指定字段进行计算后的值,类型均为double。
Terms Aggregation 统计value的去重个数,仅支持keyword类型字段,支持嵌套子聚合,参数说明如下:
  • terms
    • field:聚合字段,仅支持keyword类型字段。
    • size:返回查询结果的数量,默认为10,取值范围为[1,65536)。
    • order:返回object的排序规则,取值如下:
      • _count(默认):按结果数量排序,取值为desc(降序,默认)和asc(升序),示例为"order":{"_count":"desc"}
      • _key:按目标字段的字符排序,取值为desc(降序)和asc(升序),示例为"order":{"_key":"desc"}
    • min_doc_count:最小文档数,默认为1,查询结果的文档数若小于该数量将不显示。
    • include:指定value需包含或匹配的字符串,当目标字段为String类型时,支持正则匹配;当目标字段为数组时,需完全匹配字符串。
    • exclude:指定value不能包含或匹配的字符串,目标字段的类型要求与include相同,若同时存在includeexclude,将先检查include再检查exclude
部分请求示例:
{
  "aggs": {
    "Per_Investor_Freq":{
      "terms": {
        "field": "investor"
      }
    }
  }
}
返回结果:聚合名称为key,类型为Object的JSON内容。Object中以buckets为数组key,数组中的value为对应key和doc_count统计结果。示例如下:
{
  "aggregations": {
    "Per_Investor_Freq": {
      "buckets": [
        {
          "doc_count": 2,
          "key": "Jay"
        },
        {
          "doc_count": 1,
          "key": "Mila"
        }
      ]
    }
  }
 }
Filter Aggregation filter中可输入query语句,对query查询结果进行再次过滤,支持嵌套子聚合。

返回结果:符合过滤条件的文档个数(doc_count)。

Aggregations查询示例

  1. 创建索引。
    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"}}}}'
    # 创建今日股票交易量索引
    # shares_name:股票名称
    # logictime:成交时间点
    # purchase_type:购买类型
    # purchase_price:成交价格
    # purchase_count:成交数
    # investor:投资者ID

    预计输出:

    OK
  2. 添加文档数据。
    依次执行如下命令。
    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"}';

    预计输出:

    OK
  3. 进行查询。
    查询示例如下:
    # 查询Jay购买股票的总金额。
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Sum":{"sum":{"field":"purchase_price"}}}}'
    
    # 预期输出:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Sum":{"value":212.2}}}"
    # 查询Jay购买单只股票的最大金额。
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Max":{"max":{"field":"purchase_price"}}}}'
    
    # 预期输出:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Max":{"value":111.1}}}"
    # 查询Jay购买不同股票的平均金额。
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Avg":{"avg":{"field":"purchase_price"}}}}'
    
    # 预期输出:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Avg":{"value":106.1}}}"
    # 查询Jay购买股票金额的标准差。
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Std_Deviation":{"std_deviation":{"field":"purchase_price"}}}}'
    
    # 预期输出:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":2}},"aggregations":{"Jay_Std_Deviation":{"value":5.0}}}"
    # 查询Jay购买股票的整体行情(各指标值)。
    TFT.SEARCH today_shares '{"size":0,"query":{"term":{"investor":"Jay"}},"aggs":{"Jay_Extended_Stats":{"extended_stats":{"field":"purchase_price"}}}}'
    
    # 预期输出:
    "{"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}}}"
    # 统计交易2笔以上的投资者。
    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"}}}}}'
    
    # 预期输出:
    "{"hits":{"hits":[],"max_score":null,"total":{"relation":"eq","value":3}},"aggregations":{"Per_Investor_Freq":{"buckets":[{"key":"Jay","doc_count":2}]}}}"
    # 统计各股票的交易记录总数以及每种股票的平均成交额,但不包含“XAX”股票。
    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"}}}}}}'
    
    # 预期输出:
    "{"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}}]}}}"
    # 统计Jay购买股票的数量与整体行情(各指标值)。
    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"}}}}}}'
    
    # 预期输出:
    "{"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}}}}"