訂單系統在各行各業中普遍應用,爲消費者、商家後臺、促銷系統等第三方提供用戶、產品、訂單等多維度的管理和查詢服務。
爲了挖掘出海量訂單數據的潛能,豐富高效的查詢必不可少。然而不少時候並不能給出完整準確的查詢關鍵字,例如,只知道收貨人姓氏,或是產品名稱部分關鍵字,或是根據收貨人手機尾號找到訂單,咱們將這類查詢歸爲「模糊查詢」。數組
訂單系統,做爲電商系統的「核心」,管理着訂單狀態、商品信息、用戶信息、收貨地址和支付信息,聯動庫存更新,爲下游的倉庫物流系統提供依據。在訂單表設計時,須要記錄上述全部信息。本文僅以海量訂單管理查詢爲背景,摘選部分重要字段,管窺多元索引(SearchIndex)在模糊查詢時的一些典型使用,整理以下:性能
MySql和PostgreSQL等關係型DB支持like語法進行模糊查詢,其本質就是用查詢關鍵詞去掃描並匹配每條記錄的字符串內容,只適用於小規模地檢索,數據規模大了之後性能很是差。spa
表格存儲(TableStore)引入多元索引(SearchIndex)功能後,徹底覆蓋傳統SQL所支持的前綴匹配和通配符匹配,而且提供針對不一樣場景的精細化模糊查詢功能,性能優異。本節將以電商訂單爲背景逐一講解。設計
定義手機號字段consumerCell爲KEYWORD類型,建立多元索引,用PrefixQuery便可對原始字段進行前綴匹配查詢。例如,查詢consumerCell字段以'135'開頭的行,等價於SQL中子句consumerCell like '135%'。code
核心代碼索引
//建立索引 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。md5
核心代碼字符串
//建立索引 //等價於: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時需謹慎。get
核心代碼string
//建立索引 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)爲例,可能包含如下字段:
列名數據類型索引類型字段說明order_id_md5string-主鍵列:md5(order_id)避免熱點order_idstringKEYWORD主鍵列:訂單idorder_statuslongLONG訂單狀態order_timelongLONG下單時間pay_timelongLONG支付時間deliver_timelongLONG發貨時間receive_timelongLONG收貨時間product_idstringKEYWORD商品idproduct_namestringTEXT產品名product_typestringTEXT產品型號consumer_idstringKEYWORD收貨人idconsumer_namestringTEXT收貨人姓名consumer_cellstringKEYWORD收貨人聯繫方式consumer_addressstringTEXT收貨地址
完整代碼在這裏找到:稍後開源,敬請期待
除了上文提到的SingleWord和Fuzzy分詞器之外,多元索引還支持如下分詞器——
MaxWord分詞器將英文切分紅單詞,將中文切分紅儘量多的詞語/詞組。對中文分詞時,會作多層語義分詞,通常爲兩層,第一層按最短語義切分,第二層按最長語義切分,並將兩次切分後的數組合並。例如字符串"菊花茶",第一層切分爲["菊花"、"花茶"],第二層切分爲["菊花茶"],合併後爲["菊花"、"花茶"、"菊花茶"]。
MinWord分詞器將英文切分紅單詞,將中文切分爲儘量少的詞語/詞組。對中文分詞時,只會按最長語義切分,例如字符串"菊花茶",會被切分爲["菊花茶"]。
Split分詞器容許您按照自定義分隔符對字符串進行分詞。例如,用字符串內容用逗號(","),將Split分詞器的分隔符設置爲",",能夠按照","切分並構建索引。
表格存儲多元索引(SearchIndex)爲海量訂單數據提供了豐富的查詢類型,而模糊查詢使得用戶在不給出完整準確的查詢關鍵字就能實現近似匹配,大大提高了訂單數據的查詢易用性,發揮出存儲的更多潛在價值。
本文爲雲棲社區原創內容,未經容許不得轉載。