本文介紹如何在多種查詢情境下通過搜尋索引查詢Lindorm寬表資料,包括多維查詢、排序翻頁、分詞查詢、模糊查詢和彙總分析。
前提條件
已通過Lindorm-cli串連寬表引擎。具體操作,請參見通過Lindorm-cli串連並使用寬表引擎。
已準備測試資料並建立搜尋索引。具體內容,請參見管理搜尋索引。
多維查詢
執行以下語句實現多維查詢。
樣本一
SELECT * FROM search_table WHERE gender='M' AND city='杭州' OR city='北京';查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 6 | 李先生 | 32 | M | 杭州市餘杭區 | a***@example.net | 杭州 | | 1 | 張先生 | 18 | M | 北京市朝陽區 | a***@example.net | 北京 | | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+樣本二
SELECT * FROM search_table WHERE age > 30 AND city != '杭州';查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 28 | 陳女士 | 36 | F | 深圳市南山區 | a***@example.net | 深圳 | +---------+--------+-----+--------+--------------+------------------+------+
排序翻頁
搜尋索引支援任意列的排序,執行以下語句實現資料排序查詢。
SELECT * FROM search_table WHERE gender='M' ORDER BY age DESC;查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 6 | 李先生 | 32 | M | 杭州市餘杭區 | a***@example.net | 杭州 | | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | | 1 | 張先生 | 18 | M | 北京市朝陽區 | a***@example.net | 北京 | +---------+--------+-----+--------+--------------+------------------+------+搜尋索引支援通過
limit或者offset方式進行資料翻頁,執行以下語句實現資料翻頁查詢。SELECT * FROM search_table WHERE gender='M' ORDER BY age DESC LIMIT 1,10;查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | | 1 | 張先生 | 18 | M | 北京市朝陽區 | a***@example.net | 北京 | +---------+--------+-----+--------+--------------+------------------+------+
模糊查詢
執行以下語句查詢email列中包含example的資料。
SELECT * FROM search_table WHERE email LIKE '%example%';查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+
| user_id | name | age | gender | address | email | city |
+---------+--------+-----+--------+--------------+------------------+------+
| 1 | 張先生 | 18 | M | 北京市朝陽區 | a***@example.net | 北京 |
| 6 | 李先生 | 32 | M | 杭州市餘杭區 | a***@example.net | 杭州 |
| 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 |
| 28 | 陳女士 | 36 | F | 深圳市南山區 | a***@example.net | 深圳 |
+---------+--------+-----+--------+--------------+------------------+------+模糊查詢的效能受限於表的資料量,推薦使用分詞查詢。
彙總分析
搜尋索引支援常用的彙總函式,例如COUNT、SUM、AVG、MIN、MAX。同時,搜尋索引也支援DISTINCT和GROUP BY功能。
執行以下語句,查詢
city為杭州的資料的總數。SELECT COUNT(*) FROM search_table WHERE city='杭州';查詢結果如下:
+----------+ | EXPR$0 | +----------+ | 2 | +----------+執行以下語句,實現資料統計去重查詢。
SELECT distinct(age) FROM search_table WHERE gender='M';查詢結果如下:
+---------------+ | DISTINCT(age) | +---------------+ | 18 | | 28 | | 32 | +---------------+執行以下語句,實現分組查詢。
SELECT city,count(*) AS cnt FROM search_table WHERE gender='M' GROUP BY city ORDER BY cnt DESC ;查詢結果如下:
+------+-----+ | city | cnt | +------+-----+ | 杭州 | 2 | | 北京 | 1 | +------+-----+
彙總查詢時,如果未指定WHERE條件,將無法命中搜尋索引。此時可以在WHERE關鍵字前添加HINT參數:_l_force_index_,強制使用搜尋索引。_l_force_index_參數的詳細介紹及使用樣本,請參見hintOption參數說明和樣本四:使用_l_force_index_強制選擇索引。
分詞查詢
對於分詞列,可通過MATCH函數實現分詞查詢。
以下樣本查詢
age的範圍在(10,30]並且address匹配杭州的資料,其中address列是分詞列。SELECT * FROM search_table WHERE age > 10 AND age <= 30 AND MATCH (address) AGAINST ('杭州');查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+以下樣本查詢
age的範圍在(30,35]並且address匹配完整短語杭州市餘杭區的資料,其中address列是分詞列。SELECT * FROM search_table WHERE age > 30 AND age <= 35 AND MATCH (address) AGAINST ('"杭州市餘杭區"');查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 6 | 李先生 | 32 | M | 杭州市餘杭區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+
在寬表引擎2.7.2以下版本中,可使用等值查詢文法
=實現分詞查詢。以下樣本查詢
age的範圍在(10,30]並且address匹配杭州的資料,其中address列是分詞列。SELECT * FROM search_table WHERE age > 10 AND age <= 30 AND address = '杭州';查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+
使用分詞子欄位功能查詢
分詞子欄位功能需要寬表引擎為2.8.0及以上版本,且搜尋引擎為Elasticsearch相容版本。如果您的版本不滿足以上條件,請先升級小版本。
背景介紹
在建立搜尋索引時,如果寬表的VARCHAR欄位設定為分詞類型(即type=text),系統會在等值查詢、模糊查詢等情境中使用分詞模式進行匹配,這可能會產生非預期的檢索結果。
例如,將address設定為分詞列:address(type=text,analyzer=ik),則系統在建立索引時會按照分詞器策略將詞彙拆分為多個獨立詞項,以杭州市濱江區為例,建立索引時會被拆分為杭州市和濱江區。因此當使用LIKE進行模糊查詢時,可能因為目標詞彙被拆分而無法匹配到。
如下樣本,由於市和濱江被拆分至兩個詞彙中導致無法命中,因此返回結果為空白。
SELECT * FROM search_table WHERE city LIKE '%市濱江%' LIMIT 10;啟用方法
若需要讓VARCHAR欄位同時支援分詞查詢、模糊查詢和等值查詢情境,可啟用分詞子欄位功能。
開啟該功能,需要在建立索引時就設定對應欄位的屬性為type=string,textSubField=true,analyzer=ik,analyzer分詞器類型可根據實際使用情境選擇。樣本如下:
CREATE INDEX idx USING SEARCH ON search_table(user_id,address(type=string, textSubField=true, analyzer=ik));若已存在搜尋索引且需要啟用分詞子欄位功能,可以使用單表多搜尋索引(公測中),建立一張使用分詞子欄位的搜尋索引,將查詢切換到新索引上。
查詢方式
在查詢時,等值查詢和模糊查詢預設使用原始的完整字串匹配,分詞查詢通過MATCH函數匹配過濾條件。以下是三種常見查詢方式的樣本及其查詢結果。
等值查詢
樣本1:
SELECT * FROM search_table WHERE address='杭州' LIMIT 10;返回結果為空白,因為
address不存在完全符合杭州整個字串的記錄。樣本2:
SELECT * FROM search_table WHERE address='杭州市濱江區' LIMIT 10;查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+模糊查詢
樣本:
SELECT * FROM search_table WHERE address like '%市濱江%' LIMIT 10;查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+分詞查詢
樣本:
SELECT * FROM search_table WHERE MATCH (address) AGAINST ('杭州') LIMIT 10;查詢結果如下:
+---------+--------+-----+--------+--------------+------------------+------+ | user_id | name | age | gender | address | email | city | +---------+--------+-----+--------+--------------+------------------+------+ | 6 | 李先生 | 32 | M | 杭州市餘杭區 | a***@example.net | 杭州 | | 20 | 王先生 | 28 | M | 杭州市濱江區 | a***@example.net | 杭州 | +---------+--------+-----+--------+--------------+------------------+------+