TairSearch是Tair全自研的全文檢索搜尋資料結構,採用和Elasticsearch相似(ES-LIKE)的查詢文法。
TairSearch簡介
TairSearch具有如下主要特點:
低延遲、高效能:依託Tair的超高效能運算能力,提供毫秒層級的寫入和全文檢索搜尋能力,更多資訊請參見TairSearch效能白皮書。
增量、局部更新:支援文檔的累加式更新與局部索引更新,包括追加欄位、更新欄位、刪除欄位以及欄位自增等。
文法靈活:支援更加靈活、可讀性更強的JSON查詢文法,提供Bool、Match、Term、分頁等查詢功能,文法與Elasticsearch類似,同時支援自訂排序。
彙總查詢:支援Terms、Metrics、Filter等彙總運算元,更多資訊請參見Aggregations介紹。
Auto-complete Suggestion:支援首碼模糊搜尋、自動補全等功能。
分詞定製:提供豐富、強大的分詞器,內建英文(Standard、Stop等)、中文(Jieba、IK)及世界主要語言分詞器,同時支援Custom自訂分詞器,允許自訂使用者字典和停用詞等,更多資訊請參見Search分詞器。
索引分區查詢:支援使用TFT.MSEARCH命令同時對多個索引分區(Shard index)進行查詢,並自動返回已彙總的結果集。
壓縮儲存:支援文檔層級的壓縮儲存(預設未開啟),從而節省記憶體佔用空間。
查詢快取:支援將最近的查詢結果(可自訂)儲存在緩衝,從而提高熱點資料的查詢效率。
發布記錄
記憶體型(相容Redis 5.0)
2022年03月11日發布1.7.27版本,首次發布TairSearch。
2022年05月24日發布1.8.5版本,支援TairSearch Aggregations(彙總)功能。
2022年09月06日發布5.0.15版本,支援TFT.MSEARCH功能。
2023年01月13日發布5.0.25版本,全面支援分詞器架構。
2023年03月15日發布5.0.28版本,支援查詢快取,支援文檔壓縮儲存,新增TFT.ANALYZER命令。
2023年06月12日發布5.0.35版本,支援數群組類型的文檔,支援Okapi BM25演算法。
記憶體型(相容Redis 6.0)
2023年02月07日發布6.2.4.1版本,首次支援TairSearch。
該版本能力對齊記憶體型(相容Redis 5.0)的5.0.25版本。
2023年03月14日發布6.2.5.0版本,支援查詢快取,支援文檔壓縮儲存,新增TFT.ANALYZER命令。
該版本能力對齊記憶體型(相容Redis 5.0)的5.0.28版本。
2023年06月12日發布6.2.7.3版本,支援數群組類型的文檔,支援Okapi BM25演算法。
該版本能力對齊記憶體型(相容Redis 5.0)的5.0.35版本。
2023年12月21日發布23.12.1.2版本,支援TFT.EXPLAINSCORE命令。
最佳實務
前提條件
最新小版本將提供更豐富的功能與穩定的服務,建議將執行個體的小版本升級到最新,具體操作請參見升級小版本。如果您的執行個體為叢集執行個體或讀寫分離架構,請將代理節點的小版本也升級到最新,否則可能出現命令無法識別的情況。
注意事項
操作對象為Tair執行個體中的TairSearch資料。
為節省記憶體,推薦使用如下方法:
建立索引(index)時請將文檔中需要建立(反向)索引的欄位設定為索引欄位(將欄位的index設定為true),其餘欄位的index設定為false。
使用_source參數中的include與exclude機制剔除來源文件中不需要的欄位(field),儲存需要的資訊。
若文檔需要進行分詞處理,請選擇合適的分詞器,避免不合適的分詞器拆成出過多、無用的Token(詞元),增加記憶體開銷。
若文檔較大,您可以合理使用文檔壓縮功能對文檔進行透明壓縮(自動壓縮、解壓)。
避免在單個索引中插入過多的文檔,建議將文檔存入多個不同的索引中,並控制單個索引的文檔數在500萬以下,從而規避(叢集)執行個體發生資料扭曲,均衡讀寫流量,避免造成大Key與熱key。
命令列表
表 1. 全文檢索索引命令
命令 | 文法 | 說明 |
| 建立索引(index)並添加映射(mappings),映射文法類似ES文法。在添加索引文檔前,必須先建立索引。 | |
| 向指定的索引中新增properties欄位,或修改索引設定。 | |
| 擷取索引的映射內容。 | |
| 向索引中插入一個文檔(document),可通過WITH_ID指定該文檔在索引內的唯一ID(doc_id),若doc_id已存在,則更新並覆蓋原文檔。若不指定WITH_ID(預設),則自動產生doc_id。 | |
| 向索引中插入多個文檔(document),每個文檔必須指定文檔ID(doc_id)。若某個文檔寫入失敗(例如寫入的文檔內容與定義的格式不符),則該命令的所有文檔均不會寫入。 | |
| 更新索引中doc_id指定的文檔,若更新的欄位為mapping指定的索引欄位時,該欄位更新的內容需與mapping指定的類型一致;若停用字詞段,支援更新任意欄位類型的內容。 說明 若更新的欄位已存在,則更新原文檔,若欄位不存在,則新增該欄位。若指定的文檔不存在,該命令支援自動建立文檔,此時效果等同於TFT.ADDDOC。 | |
| 刪除索引中doc_id指定文檔的指定欄位,若該欄位為索引欄位,會同時在索引中刪除該欄位的資訊。 說明 若指定的欄位不存在(例如被_source過濾的欄位),則操作失敗。 | |
| 向索引中doc_id指定文檔的指定欄位增加整數值(increment),支援指定increment為負數,支援指定的欄位類型為long或int類型。 說明 若指定的文檔不存在,該命令支援自動建立文檔,初始化欄位的值為0,並增加指定的increment。若指定的欄位不存在(例如被_source過濾的欄位),則操作失敗。 | |
| 向索引中doc_id指定文檔的指定欄位增加浮點數值(increment),支援指定increment為負數,支援指定的欄位類型為double類型。 說明 若指定的文檔不存在,該命令支援自動建立文檔,初始化欄位的值為0,並增加指定的increment。若指定的欄位不存在(例如被_source過濾的欄位),則操作失敗。 | |
| 擷取索引中指定doc_id的文檔內容。 | |
| 查詢索引中指定doc_id的文檔是否存在。 | |
| 擷取索引中的文檔數量。 | |
| 擷取索引中所有的doc_id。 | |
| 刪除索引中doc_id指定的文檔,支援指定多個doc_id。 | |
| 刪除索引中所有文檔,但不會刪除index。 | |
| 查詢分詞器分詞效果。 | |
| 根據query語句搜尋索引的文檔,query文法類似ES文法。 | |
| 根據query語句搜尋多個索引的文檔(待查詢索引的mappings和settings的配置必須相同),匯聚多個索引的查詢結果,再次進行打分、排序、彙總並返回。 | |
| 查詢query語句的執行耗時,返回內容包括查詢過程中涉及到的文檔集合數及各階段的耗時。 | |
| 查詢執行query語句的計分詳情資訊,您可以通過該命令瞭解文檔分數的計算過程,並最佳化Search語句,提升文檔的查詢效果。 | |
| 使用原生Redis的DEL命令可以刪除一條或多條TairSearch資料。 |
表 2. 自動補齊命令
命令 | 文法 | 說明 |
| 在指定索引中,添加自動補全的文本及對應權重,支援添加多個文本。 | |
| 在指定索引中,刪除自動補全的文本,支援刪除多個文本。 | |
| 擷取指定索引中自動補全文本的數量。 | |
| 根據指定首碼,查詢匹配的自動補全文本,將優先返回權重比較高的text。 | |
| 擷取指定索引的全量自動補全文本。 |
本文的命令文法定義如下:
大寫關鍵字
:命令關鍵字。斜體
:變數。[options]
:選擇性參數,不在括弧中的參數為必選。A|B
:該組參數互斥,請進行二選一或多選一。...
:前面的內容可重複。
TFT.CREATEINDEX
類別 | 說明 |
文法 |
|
命令描述 | 建立索引(index)並添加映射(mappings),映射文法類似ES文法。在添加索引文檔前,必須先建立索引。 說明 為避免產生大Key,您可以預先將大索引拆分成小索引,並設計負載規則將資料寫入不同的索引中。建立該類索引時,必須使該類索引具備相同的mappings和settings配置,建立後可通過TFT.MSEARCH進行查詢。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.UPDATEINDEX
類別 | 說明 |
文法 |
|
命令描述 | 向指定的索引中新增properties欄位,或修改索引設定。 |
選項 |
說明 mappings和settings的文法請參見TFT.CREATEINDEX。 |
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.GETINDEX
類別 | 說明 |
文法 |
|
命令描述 | 擷取索引的映射內容。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.ADDDOC
類別 | 說明 |
文法 |
|
命令描述 | 向索引中插入一個文檔(document),可通過WITH_ID指定該文檔在索引內的唯一ID(doc_id),若doc_id已存在,則更新並覆蓋原文檔。若不指定WITH_ID(預設),則自動產生doc_id。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
數組的添加樣本:
|
TFT.MADDDOC
類別 | 說明 |
文法 |
|
命令描述 | 向索引中插入多個文檔(document),每個文檔必須指定文檔ID(doc_id)。若某個文檔寫入失敗(例如寫入的文檔內容與定義的格式不符),則該命令的所有文檔均不會寫入。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.UPDATEDOCFIELD
類別 | 說明 |
文法 |
|
命令描述 | 更新索引中doc_id指定的文檔,若更新的欄位為mapping指定的索引欄位時,該欄位更新的內容需與mapping指定的類型一致;若停用字詞段,支援更新任意欄位類型的內容。 說明 若更新的欄位已存在,則更新原文檔,若欄位不存在,則新增該欄位。若指定的文檔不存在,該命令支援自動建立文檔,此時效果等同於TFT.ADDDOC。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.DELDOCFIELD
類別 | 說明 |
文法 |
|
命令描述 | 刪除索引中doc_id指定文檔的指定欄位,若該欄位為索引欄位,會同時在索引中刪除該欄位的資訊。 說明 若指定的欄位不存在(例如被_source過濾的欄位),則操作失敗。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.INCRLONGDOCFIELD
類別 | 說明 |
文法 |
|
命令描述 | 向索引中doc_id指定文檔的指定欄位增加整數值(increment),支援指定increment為負數,支援指定的欄位類型為long或int類型。 說明 若指定的文檔不存在,該命令支援自動建立文檔,初始化欄位的值為0,並增加指定的increment。若指定的欄位不存在(例如被_source過濾的欄位),則操作失敗。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.INCRFLOATDOCFIELD
類別 | 說明 |
文法 |
|
命令描述 | 向索引中doc_id指定文檔的指定欄位增加浮點數值(increment),支援指定increment為負數,支援指定的欄位類型為double類型。 說明 若指定的文檔不存在,該命令支援自動建立文檔,初始化欄位的值為0,並增加指定的increment。若指定的欄位不存在(例如被_source過濾的欄位),則操作失敗。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.GETDOC
類別 | 說明 |
文法 |
|
命令描述 | 擷取索引中指定doc_id的文檔內容。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.EXISTS
類別 | 說明 |
文法 |
|
命令描述 | 查詢索引中指定doc_id的文檔是否存在。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.DOCNUM
類別 | 說明 |
文法 |
|
命令描述 | 擷取索引中的文檔數量。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.SCANDOCID
類別 | 說明 |
文法 |
|
命令描述 | 擷取索引中所有的doc_id。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.DELDOC
類別 | 說明 |
文法 |
|
命令描述 | 刪除索引中doc_id指定的文檔,支援指定多個doc_id。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.DELALL
類別 | 說明 |
文法 |
|
命令描述 | 刪除索引中所有文檔,但不會刪除index。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.ANALYZER
類別 | 說明 |
文法 |
|
命令描述 | 查詢分詞器分詞效果。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.SEARCH
類別 | 說明 |
文法 |
|
命令描述 | 根據query語句搜尋索引的文檔,query文法類似ES文法。 |
選項 | index為待查詢的索引名稱;query為類似ES文法的DLS語句,支援如下欄位:
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.MSEARCH
類別 | 說明 |
文法 |
|
命令描述 | 根據query語句搜尋多個索引的文檔(待查詢索引的mappings和settings的配置必須相同),匯聚多個索引的查詢結果,再次進行打分、排序、彙總並返回。 說明 TFT.MSEARCH命令返回的結果是對多個索引的查詢結果再次進行打分、排序、彙總的結果,該結果不等同於對多個索引的資料集合直接進行打分、排序、彙總等結果。TFT.MSEARCH的策略如下:
|
選項 |
說明 相比較TFT.SEARCH的query語句,TFT.MSEARCH的query不支援from參數,但可以通過size、reply_with_keys_cursor與keys_cursor參數實現分頁查詢,其餘參數文法均可參見TFT.SEARCH。 |
傳回值 |
|
樣本 | 提前執行如下命令:
命令樣本:
返回樣本:
第二頁查詢命令樣本:
返回樣本:
|
TFT.EXPLAINCOST
類別 | 說明 |
文法 |
|
命令描述 | 查詢query語句的執行耗時,返回內容包括查詢過程中涉及到的文檔集合數及各階段的耗時。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.EXPLAINSCORE
類別 | 說明 |
文法 |
|
命令描述 | 查詢執行query語句的計分詳情資訊,您可以通過該命令瞭解文檔分數的計算過程,並最佳化Search語句,提升文檔的查詢效果。 該命令當前僅記憶體型(相容Redis 6.0)支援。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.ADDSUG
類別 | 說明 |
文法 |
|
命令描述 | 在指定索引中,添加自動補全的文本及對應權重,支援添加多個文本。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.DELSUG
類別 | 說明 |
文法 |
|
命令描述 | 在指定索引中,刪除自動補全的文本,支援刪除多個文本。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.SUGNUM
類別 | 說明 |
文法 |
|
命令描述 | 擷取指定索引中自動補全文本的數量。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.GETSUG
類別 | 說明 |
文法 |
|
命令描述 | 根據指定首碼,查詢匹配的自動補全文本,將優先返回權重比較高的text。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
TFT.GETALLSUGS
類別 | 說明 |
文法 |
|
命令描述 | 擷取指定索引的全量自動補全文本。 |
選項 |
|
傳回值 |
|
樣本 | 命令樣本:
返回樣本:
|
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等)欄位進行數值計算或統計,不支援嵌套子彙總。支援如下指標:
說明 除value_count外,其餘指標均只支援數實值型別欄位。 返回結果:指定欄位進行計算後的值,類型均為double。 |
Terms Aggregation | 統計value的去重個數,僅支援keyword類型欄位,支援嵌套子彙總,參數說明如下:
部分請求樣本:
返回結果:彙總名稱為key,類型為Object的JSON內容。Object中以buckets為數組key,數組中的value為對應key和doc_count統計結果。樣本如下:
|
Filter Aggregation | filter中可輸入query語句,對query查詢結果進行再次過濾,支援嵌套子彙總。 返回結果:符合過濾條件的文檔個數(doc_count)。 |
Aggregations查詢樣本
建立索引。
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
添加文檔資料。
依次執行如下命令。
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
進行查詢。
查詢樣本如下:
sum
# 查詢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}}}
max
# 查詢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}}}
avg
# 查詢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}}}
std_deviation
# 查詢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}}}
extended_stats
# 查詢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}}}
terms
# 統計交易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}]}}}
terms嵌套
# 統計各股票的交易記錄總數以及每種股票的平均成交額,但不包含“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}}]}}}
filter嵌套
# 統計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}}}}