詳解TableStore模糊查詢——以訂單場景爲例

背景
訂單系統在各行各業中廣泛應用,爲消費者、商家後臺、促銷系統等第三方提供用戶、產品、訂單等多維度的管理和查詢服務。
爲了挖掘出海量訂單數據的潛能,豐富高效的查詢必不可少。然而很多時候並不能給出完整準確的查詢關鍵字,例如,只知道收貨人姓氏,或是產品名稱部分關鍵字,或是根據收貨人手機尾號找到訂單,我們將這類查詢歸爲“模糊查詢”。

需求分析
訂單系統,作爲電商系統的“核心”,管理着訂單狀態、商品信息、用戶信息、收貨地址和支付信息,聯動庫存更新,爲下游的倉庫物流系統提供依據。在訂單表設計時,需要記錄上述所有信息。本文僅以海量訂單管理查詢爲背景,摘選部分重要字段,管窺多元索引(SearchIndex)在模糊查詢時的一些典型使用,整理如下:

手機號前綴匹配
覆蓋SQL like語義,滿足前綴匹配、後綴匹配和通配符匹配查詢。
產品名稱模糊查詢
用戶輸入產品名稱中部分關鍵字即可查出包含相關產品的訂單。
商品型號的實時查詢提示
只輸入少量查詢關鍵字就可召回儘可能多的匹配結果,可用於“電影名稱”、“產品型號”等字段的實時查詢提示。

傳統解法
MySql和PostgreSQL等關係型DB支持like語法進行模糊查詢,其本質就是用查詢關鍵詞去掃描並匹配每條記錄的字符串內容,只適用於小規模地檢索,數據規模大了以後性能非常差。

TableStore解法
表格存儲(TableStore)引入多元索引(SearchIndex)功能後,完全覆蓋傳統SQL所支持的前綴匹配和通配符匹配,並且提供針對不同場景的精細化模糊查詢功能,性能優異。本節將以電商訂單爲背景逐一講解。

手機號前綴匹配
定義手機號字段consumerCell爲KEYWORD類型,創建多元索引,用PrefixQuery即可對原始字段進行前綴匹配查詢。例如,查詢consumerCell字段以'135'開頭的行,等價於SQL中子句consumerCell like '135%'。

核心代碼

//創建索引
indexSchema.addFieldSchema(new FieldSchema(CONSUMER_CELL, FieldType.KEYWORD));

//查詢
PrefixQuery prefixQuery = new PrefixQuery();
prefixQuery.setFieldName(CONSUMER_CELL);
prefixQuery.setPrefix("13580");

通配符查詢
如同前綴查詢(PrefixQuery),通配符查詢(WildcardQuery)可以對原始字符串進行更靈活一些的匹配。例如,查詢consumerCell字段中以'135'開頭並且中間包含'8066'的行,類比SQL中子句consumerCell like '135%8066%'。在表格存儲中可以把consumerCell定義爲KEYWORD類型,建立多元索引,然後用WildcardQuery進行通配符匹配。要匹配的值可以是一個帶有通配符的字符串,用星號("")代表0個或多個任意字符,用問號("?")代表任意單個字符。
需要注意的是,不能以“
”開頭,且模式字符長度不能超過10字節。

如何實現後綴匹配
通配符查詢不能以“*”開頭,若要實現後綴匹配,可將字符串翻轉,再用PrefixQuery/WildcardQuery查詢。

產品名稱模糊查詢
在訂單場景中,“收貨人姓名”、“產品名”和“收貨地址”這類字段可能包含漢字、英文、數字等,查詢時需要以“單個漢字”或“英文單詞”爲粒度切分字符串並建立索引。查詢同理,以“單個漢字”或“英文單詞”爲粒度對查詢關鍵詞字符串進行分詞,在索引中進行查找匹配。

例如,訂單表中,某行的產品名稱字段值爲"Xiaomi/小米redmi note 7 pro 紅米索尼4800萬智能手機",期望用"xiaomi", "小米", "note", "pro"都能匹配到該條記錄。可以使用默認分詞器SingleWord分詞器。

TEXT類型索引列默認使用SingleWord分詞器,按“單個漢字”切分中文,按“單個單詞”切分英文,大小寫字母不敏感,且單詞不會被拆分爲子詞。例如,字段值"Xiaomi/小米redmi note 7 pro 紅米索尼4800萬智能手機"會被切分爲詞條:"xiaomi", "小", "米", "redmi", "note", "7", "pro", "紅", "米", "索", "尼", "4800", "萬", "智", "能", "手", "機",並建立倒排索引。

SingleWord支持配置參數CaseSensitive設置是否大小寫敏感;參數DelimitWord表示是否將單詞拆成子詞。例如,當設置SingleWord的參數DelimitWord=true, CaseSensitive=true,TEXT字段值"TableStore"會被切分爲"Table"和"Store"。

查詢時若不在乎查詢關鍵詞分詞後的順序,用MatchQuery即可滿足需求。對於特定場景,對查詢關鍵詞被被分詞後順序敏感,可以考慮使用MatchPhraseQuery。

核心代碼

//創建索引
//等價於:indexSchema.addFieldSchema(new FieldSchema(PRODUCT_NAME, FieldType.TEXT));
indexSchema.addFieldSchema(new FieldSchema(PRODUCT_NAME, FieldType.TEXT).setAnalyzer(FieldSchema.Analyzer.SingleWord));

//查詢
MatchQuery matchQuery = new MatchQuery();
matchQuery.setFieldName(PRODUCT_NAME);
matchQuery.setText("Xiaomi/小米redmi note 7 pro 紅米索尼4800萬智能手機");

商品型號的實時查詢提示
某些場景下,當使用者在搜索框中鍵入部分關鍵字,就召回儘可能多的結果。這樣,可以避免用戶輸入錯誤的關鍵字,將其引導到“意中有語中無”的正確結果,提升用戶體驗。例如,訂單表中包含某手機型號爲"HUAWEI P30PRO",一種良好的查詢體驗是:僅當鍵入"P30","30"或者"PRO"時,就可以查出這行記錄並反饋用戶。此時,您可以考慮使用Fuzzy分詞器。

Fuzzy分詞器可以對字符串進行最細粒度的拆分,可以提升查詢召回率,但也造成多元索引存儲量膨脹,因此需要謹慎使用。其原理是設置一個“最小字符串長度窗口(minChars)”和“最大字符串長度窗口(maxChars)”,遍歷[minChars, maxChars]窗口大小對TEXT類型字段值進行切分,並對所有切分後的字符串建立倒排。minChars默認爲1,maxChars默認爲3。

對“產品型號”建立TEXT索引,並使用Fuzzy分詞器以後,字段值"HUAWEI P30PRO"會被切分爲詞條:"h", "hu", "hua", "u", "ua", "uaw", "a", "aw", "awe", "w", "we", "wei", "e", "ei", "i", "p", "p3", "p30", "3", "30", "30p", "0", "0p", "0pr", "pr", "pro", "r", "ro", "o",並建立倒排索引。因此,用"p30", "P30", "30", "PRO", "pro"查詢時都可以匹配到。同時也可以看出,Fuzzy分詞後索引數據量急劇膨脹,因此限制maxChars和minChars的差值不超過6,如果您需要自定義minChars和maxChars時需謹慎。

核心代碼

//創建索引
indexSchema.addFieldSchema(new FieldSchema(PRODUCT_TYPE, FieldType.TEXT)
.setAnalyzer(FieldSchema.Analyzer.Fuzzy)
.setAnalyzerParameter(new FuzzyAnalyzerParameter(1, 4)));

//查詢
MatchQuery matchQuery = new MatchQuery();
matchQuery.setFieldName(PRODUCT_TYPE);
matchQuery.setText("P30");

代碼示例

訂單表結構
以訂單系統的訂單表(表名order)爲例,可能包含以下字段:

詳解TableStore模糊查詢——以訂單場景爲例

項目代碼
完整代碼在這裏找到:稍後開源,敬請期待

附錄
除了上文提到的SingleWord和Fuzzy分詞器以外,多元索引還支持以下分詞器——

MaxWord分詞器
MaxWord分詞器將英文切分成單詞,將中文切分成儘可能多的詞語/詞組。對中文分詞時,會做多層語義分詞,一般爲兩層,第一層按最短語義切分,第二層按最長語義切分,並將兩次切分後的數組合並。例如字符串"菊花茶",第一層切分爲["菊花"、"花茶"],第二層切分爲["菊花茶"],合併後爲["菊花"、"花茶"、"菊花茶"]。

MinWord分詞器
MinWord分詞器將英文切分成單詞,將中文切分爲儘可能少的詞語/詞組。對中文分詞時,只會按最長語義切分,例如字符串"菊花茶",會被切分爲["菊花茶"]。

Split分詞器
Split分詞器允許您按照自定義分隔符對字符串進行分詞。例如,用字符串內容用逗號(","),將Split分詞器的分隔符設置爲",",可以按照","切分並構建索引。

總結
表格存儲多元索引(SearchIndex)爲海量訂單數據提供了豐富的查詢類型,而模糊查詢使得用戶在不給出完整準確的查詢關鍵字就能實現近似匹配,大大提升了訂單數據的查詢易用性,發揮出存儲的更多潛在價值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章