Hologres自V4.0版本起支援全文倒排索引,該功能基於高效能全文檢索索引引擎Tantivy構建,提供高效能檢索能力,同時支援BM25相似性評分演算法,提供文檔排序、關鍵詞檢索、短語檢索等多方面能力。
實現原理
將檢索源文本寫入Hologres後,Hologres會根據索引配置,對每個資料檔案,構建全文倒排索引檔案。該過程首先通過分詞器對文本進行分詞,得到若干分詞token,然後通過索引記錄每個token與檢索源文本的映射關係、位置和詞頻等相關資訊。
在對文本進行檢索時,先對檢索對象文本進行分詞,得到對象token集合。通過BM25演算法計算檢索源的每個文本與檢索對象token集合的相關性分數,實現高效能、高精度的全文檢索索引。
注意事項
-
僅支援Hologres V4.0及以上版本的列存表、行列共存表使用全文倒排索引功能,不支援行存表。
-
僅支援對TEXT/CHAR/VARCHAR類型的列建立全文倒排索引。
-
僅支援對單列構建全文倒排索引。每一列僅支援構建一個全文倒排索引。如果有多列需要構建,則需要建立多個索引。
-
在建立全文倒排索引後,針對錶中現有資料及後續批量寫入的新資料,索引檔案將隨著資料的合并(Compaction)過程進行非同步構建。在索引檔案構建完成之前,資料的BM25相關性分數為0。
-
針對建立全文倒排索引後的資料即時寫入情境,在Hologres V4.0.8版本之前,索引會在資料即時寫入時同步構建。從V4.0.8版本開始,為了保障資料即時寫入的效率與索引構建的效能,系統將以1秒為間隔,定時非同步重新整理記憶體中的即時索引,只有在重新整理後,才能通過索引查詢到相關資料。
-
全文檢索索引僅支援在已建立全文索引的列上執行,不支援在未構建索引的情況下進行暴力計算。
-
建議使用Serverless Computing資源執行資料的大量匯入,Serverless資源將在資料匯入時同步完成Compaction及全文索引構建,詳情請參見使用Serverless Computing執行讀寫任務、使用Serverless Computing執行Compaction任務。如不使用Serverless資源,建議在大量匯入資料或修改索引後,手動執行如下命令觸發Compaction。
VACUUM <schema_name>.<table_name>; -
BM25檢索演算法計算的相關性分數為檔案層級,如果您的資料匯入量較小,建議按需手動觸發Compaction,以完成檔案合并,提升檢索準確率。
-
支援使用Serverless Computing資源執行全文檢索索引的查詢。
-
推薦按下表情境選擇合適的分詞器:
情境
分詞器
備忘
長文章關鍵詞提取
Jieba
支援新詞發現、複雜模式切換。
中文描述類文本檢索
IK
精確識別中文術語。
英文標題類文本檢索
Simple、Whitespace、Standard
簡單高效,根據目標英文文本按需使用。
日誌類文本模糊檢索
Ngram
無需詞典,滿足文本的模糊查詢需求。
中文商品/人名拼音檢索
Pinyin
中文全拼、首字母、多音字推導等豐富的中文拼音情境。
管理索引
建立索引
文法格式
CREATE INDEX [ IF NOT EXISTS ] idx_name ON table_name
USING FULLTEXT (column_name [ , ... ])
[ WITH ( storage_parameter [ = value ] [ , ... ] ) ];
參數說明
|
參數 |
描述 |
|
idx_name |
索引名。 |
|
table_name |
目標表名。 |
|
column_name |
構建全文倒排索引的目標列名。 |
|
storage_parameter |
配置全文倒排索引參數,有如下參數:
說明
同一個索引中,僅支援設定一種tokenizer和analyzer_params。 |
index_options配置詳解
index_options支援以下三個層級,高層級選項會自動包含低層級的所有資訊:freqs 包含 docs 的資訊,positions 包含 freqs 和 docs 的資訊。
|
取值 |
索引內容 |
功能影響與限制 |
典型應用情境 |
|
positions(預設值) |
文檔編號 + 詞頻 + 詞位置(Positions) |
全功能支援:支援短語查詢及正常的相關性打分。 |
通用全文檢索索引情境 |
|
freqs |
文檔編號 + 詞頻(Term Frequencies) |
由於缺少位置資訊,執行短語查詢會報錯。 |
需要基於詞頻進行打分排序,但不需要精確短語匹配的情境 |
|
docs |
僅文檔編號(Doc ID) |
|
僅需存在性檢查(基於全文索引過濾),對儲存空間敏感且無需相關性排序的情境 |
對於使用keyword分詞器的索引,其索引記錄層級固定為docs,不受index_options的控制。
使用樣本
-
建立全文倒排索引,分詞器及配置均為預設,即jieba分詞器。
CREATE INDEX idx1 ON tbl USING FULLTEXT (col1); -
顯式指定使用ik分詞器,分詞器使用預設配置。
CREATE INDEX idx1 ON tbl USING FULLTEXT (col1) WITH (tokenizer = 'ik'); -
顯式指定使用自訂的分詞器配置: jieba分詞器+exact模式+僅用lowercase過濾器轉小寫。
CREATE INDEX idx1 ON tbl USING FULLTEXT (col1) WITH (tokenizer = 'jieba', analyzer_params = '{"tokenizer":{"type":"jieba","mode":"exact"}, "filter":["lowercase"]}'); -
建立索引時指定index_options為freqs(節省空間的,但不支援短語查詢)。Hologres V4.1.9版本起支援。
CREATE INDEX idx1 ON tbl USING FULLTEXT (col1) WITH (index_options = 'freqs');
-
建立全文倒排索引後,索引檔案將在資料匯入後的Compaction過程中構建。
-
建議使用Serverless Computing資源執行資料的大量匯入,Serverless資源將在資料匯入時同步完成Compaction及全文索引構建,參見使用Serverless Computing執行讀寫任務、使用Serverless Computing執行Compaction任務。
-
如不使用Serverless資源,建議在大量匯入資料或修改索引後,手動執行如下命令觸發Compaction,參見Compaction(Beta)。
VACUUM <schema_name>.<table_name>;
修改索引
文法格式
-- 修改索引配置
ALTER INDEX [ IF EXISTS ] <idx_name> SET ( <storage_parameter> = '<storage_value>' [ , ... ] );
-- 恢複預設配置
ALTER INDEX [ IF EXISTS ] <idx_name> RESET ( <storage_parameter> [ , ... ] );
參數說明
參數詳細說明請參見參數說明。
使用樣本
修改全文倒排索引後,索引檔案將隨資料的Compaction過程非同步構建。建議在修改索引後,手動執行VACUUM <schema_name>.<table_name>;命令,同步觸發Compaction,詳情請參見Compaction。
-
將索引的分詞器改為standard。
ALTER INDEX idx1 SET (tokenizer = 'standard'); -
將索引的分詞器改為ik,ik_max_word模式,不轉小寫,不加任何filter。
ALTER INDEX idx1 SET ( tokenizer = 'ik', analyzer_params = '{"tokenizer":{"type":"ik","mode":"ik_max_word","enable_lowercase": false}}' ); -
恢複預設分詞器jieba,且使用jieba分詞器的預設analyzer_params配置。
ALTER INDEX idx1 RESET (tokenizer); ALTER INDEX idx1 RESET (tokenizer, analyzer_params); -
恢複到當前分詞器的預設analyzer_params配置。
ALTER INDEX idx1 RESET (analyzer_params); -
將索引的index_options改為docs。
ALTER INDEX idx1 SET (index_options = 'docs'); -
恢複index_options為預設值positions。
ALTER INDEX idx1 RESET (index_options);
刪除索引
文法格式
DROP INDEX [ IF EXISTS ] <idx_name> [ RESTRICT ];
參數說明
參數詳細說明請參見參數說明。
查看索引
Hologres提供hologres.hg_index_properties系統資料表,可查看錶中已建立的全文倒排索引及對應位置。
SELECT * FROM hologres.hg_index_properties;
執行如下SQL,可查看索引對應的表和列。
SELECT
t.relname AS table_name,
a.attname AS column_name
FROM pg_class t
JOIN pg_index i ON t.oid = i.indrelid
JOIN pg_class idx ON i.indexrelid = idx.oid
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(i.indkey)
WHERE t.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '<namespace>')
AND idx.relname = '<indexname>'
LIMIT 1;
參數說明:
-
namespace:為
SELECT * FROM hologres.hg_index_properties;命令執行結果中的table_namespace欄位值。 -
indexname:為實際建立的索引名稱。
使用索引進行全文檢索索引
Hologres支援豐富的檢索模式,便於您按照商務邏輯,靈活進行全文檢索索引。
|
檢索模式 |
說明 |
|
關鍵詞匹配 |
按檢索對象的分詞結果關鍵詞進行檢索,支援定義關鍵詞間的AND/OR關係。 |
|
短語檢索 |
按檢索對象的短語進行檢索,需滿足多個詞之間的距離要求才可匹配。 |
|
自然語言檢索 |
支援自由定義複雜查詢條件,靈活實現檢索目標,如定義AND/OR關聯關係、定義必須出現詞/排除詞、定義短語等。 |
|
術語檢索 |
按檢索對象精確檢索,需要索引中精確包含查詢串才可匹配。 |
檢索函數TEXT_SEARCH
檢索函數TEXT_SEARCH可基於檢索對象文本,對檢索源文本計算BM相關性分數。
函數文法
TEXT_SEARCH (
<search_data> TEXT/VARCHAR/CHAR
,<search_expression> TEXT
[ ,<mode> TEXT DEFAULT 'match'
,<operator> TEXT DEFAULT 'OR'
,<tokenizer> TEXT DEFAULT ''
,<analyzer_params> TEXT DEFAULT ''
,<options> TEXT DEFAULT '']
)
參數說明
|
參數 |
是否必填 |
描述 |
|
search_data |
是 |
檢索源。資料類型支援TEXT/VARCHAR/CHAR,僅支援列入參,且列上需已構建全文索引,否則會報錯。 |
|
search_expression |
是 |
檢索對象。資料類型支援TEXT/VARCHAR/CHAR,僅支援常量。 |
|
mode |
否 |
檢索模式。支援的模式如下:
|
|
operator |
否 |
關鍵詞之間的邏輯運算子。僅mode為match時生效。支援如下取值:
|
|
tokenizer、analyzer_params |
否 |
對檢索對象search_expression使用的分詞器及配置,一般無需配置。
|
|
options |
否 |
全文檢索索引的其他參數。入參格式為 目前僅支援slop參數,僅mode為phrase時生效,支援slop為0(預設)或正整數,用於定義短語中各個詞之間可容忍的距離。 說明
slop表示短語組成詞之間的最大允許間隔(或轉換開銷),對於jieba/keyword/icu等tokenizer來說,間隔的單位是字元數而不是tokens單詞數。對於standard/simple/whitespace等tokenizer,間隔的單位是tokens單詞數。 |
傳回值說明
返回非負的FLOAT類型,表示檢索源與檢索對象的BM25相關性分數。相關性越高,分數越大。當文本完全不相關時,分數為0。
樣本
-
使用關鍵詞匹配模式,並將運算子改為AND。
-- 建議指定參數名 SELECT TEXT_SEARCH (content, 'machine learning', operator => 'AND') FROM tbl; -- 不指定參數名,需按入參順序顯式指定 SELECT TEXT_SEARCH (content, 'machine learning', 'match', 'AND') FROM tbl; -
使用短語檢索模式,並將slop設為2。
SELECT TEXT_SEARCH (content, 'machine learning', 'phrase', options => 'slop=2;') FROM tbl; -
使用自然語言檢索模式。
-- 通過AND、OR運算子定義分詞檢索邏輯 SELECT TEXT_SEARCH (content, 'machine AND (system OR recognition)', 'natural_language') FROM tbl; -- 通過+(必須出現詞)、-(必須排除詞)定義分詞檢索邏輯 SELECT TEXT_SEARCH (content, '+learning -machine system', 'natural_language') FROM tbl; -
使用術語檢索模式。
SELECT TEXT_SEARCH (content, 'machine learning', 'term') FROM tbl;
分詞函數TOKENIZE
分詞函數TOKENIZE可按照分詞器配置,輸出分詞結果,以便對全文倒排索引的分詞效果進行調試。
函數文法
TOKENIZE (
<search_data> TEXT
[ ,<tokenizer> TEXT DEFAULT ''
,<analyzer_params> TEXT DEFAULT '']
)
參數說明
-
search_data:必填。分詞目標文本,支援常量入參。
-
tokenizer、analyzer_params:選填。對分詞目標文本search_data使用的分詞器及配置。預設使用jieba分詞器。
傳回值說明
返回目標文本的分詞token集合,類型為TEXT數組。
索引使用驗證
可通過執行計畫查看SQL是否使用了全文倒排索引,若其中出現Fulltext Filter,表示已成功使用。執行計畫詳情請參見EXPLAIN和EXPLAIN ANALYZE。
樣本SQL:
EXPLAIN ANALYZE SELECT * FROM wiki_articles WHERE text_search(content, '長江') > 0;
執行計畫如下:其中包含Fulltext Filter欄位,表示該SQL已成功使用全文倒排索引。
QUERY PLAN
Gather (cost=0.00..1.00 rows=1 width=12)
-> Local Gather (cost=0.00..1.00 rows=1 width=12)
-> Index Scan using Clustering_index on wiki_articles (cost=0.00..1.00 rows=1 width=12)
Fulltext Filter: (text_search(content, search_expression => '長江'::text, mode => match, operator => OR, tokenizer => jieba, analyzer_params => {"filter":["removepunct","lowercase",{"stop_words":["_english_"],"type":"stop"},{"language":"english","type":"stemmer"}],"tokenizer":{"hmm":true,"mode":"search","type":"jieba"}}, options => ) > '0'::double precision)
Query Queue: init_warehouse.default_queue
Optimizer: HQO version 4.0.0
使用樣本
資料準備
執行以下SQL建立測試表、並寫入資料。
-- 建立表
CREATE TABLE wiki_articles (id int, content text);
-- 建立索引
CREATE INDEX ft_idx_1 ON wiki_articles
USING FULLTEXT (content)
WITH (tokenizer = 'jieba');
-- 寫入資料
INSERT INTO wiki_articles VALUES
(1, '長江是中國第一大河,世界第三長河,全長約6,300公裡。'),
(2, 'Li was born in 1962 in Wendeng County, Shandong.'),
(3, 'He graduated from the department of physics at Shandong University.'),
(4, '春節,即農曆新年,是中國最重要的傳統節日。'),
(5, '春節通常在西曆1月下旬至2月中旬之間。春節期間的主要習俗包括貼春聯、放鞭炮、吃年夜飯、拜年等。'),
(6, '2006年,春節被國務院批准為第一批國家級非物質文化遺產。'),
(7, 'Shandong has dozens of universities.'),
(8, 'ShanDa is a famous university of Shandong.');
-- Compaction
VACUUM wiki_articles;
-- 查詢表資料
SELECT * FROM wiki_articles limit 1;
返回結果樣本如下:
id | content
---+---------------------------------------------------
1 | 長江是中國第一大河,世界第三長河,全長約6,300公裡。
不同檢索樣本
-
關鍵詞匹配。
-- (K1) 關鍵詞匹配(預設operator=OR),包含'shandong'或'university'的文檔均能匹配。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university') > 0; --返回結果 id | content ----+--------------------------------------------------------------------- 2 | Li was born in 1962 in Wendeng County, Shandong. 3 | He graduated from the department of physics at Shandong University. 7 | Shandong has dozens of universities. 8 | ShanDa is a famous university of Shandong. -- (K2) 關鍵詞匹配(operator=AND),必須同時包含'shandong'和'university'才能匹配 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', operator => 'AND') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 3 | He graduated from the department of physics at Shandong University. 7 | Shandong has dozens of universities. 8 | ShanDa is a famous university of Shandong. -
短語檢索。
-- (P1) 短語檢索(預設slop = 0),即必須 shandong 後緊接 university 後才匹配 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', mode => 'phrase') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 3 | He graduated from the department of physics at Shandong University. (1 row) -- (P2) 短語檢索指定slop = 14,即 shandong 與 university 之間的距離不超過14個字元,那麼可以匹配“Shandong has dozens of universities.” SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', mode => 'phrase', options => 'slop=14;') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 3 | He graduated from the department of physics at Shandong University. 7 | Shandong has dozens of universities. (2 rows) -- (P3) 短語檢索支援檢索不保序的短語,但slop計算方式不一樣,要比保序的slop要大。 -- 因此'university of Shandong'也能匹配以下查詢,但slop=22時不會匹配到 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', mode => 'phrase', options => 'slop=23;') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 3 | He graduated from the department of physics at Shandong University. 7 | Shandong has dozens of universities. 8 | ShanDa is a famous university of Shandong. (3 rows) -- (P4) standard分詞索引下的表現。(ALTER INDEX ft_idx_1 SET (tokenizer = 'standard');) -- 對於standard分詞來說,slop則是以tokens為計算單位。 -- 只要中間間隔0個tokens,不管有多少空格,都算作短語匹配。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', mode => 'phrase') > 0; -- 返回結果 id | content ----+------------------------ 1 | shandong university 2 | shandong university 3 | shandong university 4 | shandong university (4 rows) -- (P5) 標點將被忽略。(jieba分詞器為例) -- 即使文本中,長河和全長之間是逗號,而查詢串是句號。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '長河。全長', mode => 'phrase') > 0; -- 返回結果 id | content ----+----------------------------------------------------- 1 | 長江是中國第一大河,世界第三長河,全長約6,300公裡。 (1 row) -
自然語言查詢。
-- (N1) 自然語言查詢:不加任何符號,預設等同於關鍵詞匹配。與(K1)等價。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', 'natural_language') > 0; id | content ----+--------------------------------------------------------------------- 7 | Shandong has dozens of universities. 2 | Li was born in 1962 in Wendeng County, Shandong. 3 | He graduated from the department of physics at Shandong University. 8 | ShanDa is a famous university of Shandong. -- (N2) 自然語言查詢:關鍵詞匹配,必須(同時包含'shandong'和'university')或者包含'文化'才匹配。AND運算子優先順序大於OR。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '(shandong AND university) OR 文化', 'natural_language') > 0; -- 等價於 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong AND university OR 文化', 'natural_language') > 0; -- 等價於 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '(+shandong +university) 文化', 'natural_language') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 8 | ShanDa is a famous university of Shandong. 7 | Shandong has dozens of universities. 3 | He graduated from the department of physics at Shandong University. 6 | 2006年,春節被國務院批准為第一批國家級非物質文化遺產。 -- (N3) 自然語言查詢:關鍵詞匹配,必須包含'shandong',必須不包含'university',可以包含'文化'。 -- 在這個查詢中'文化'關鍵詞前沒有+, -符號,不會影響哪些行會匹配上,但會影響匹配分數,帶有'文化'的匹配分數更高。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '+shandong -university 文化', 'natural_language') > 0; id | content ----+-------------------------------------------------- 2 | Li was born in 1962 in Wendeng County, Shandong. -- 必須包含'shandong',必須不包含'physics',可以包含'famous'。包含famous的相關性分數更高。 -- 註:此Query為單Shard下的分數計算結果,不同的Shard數,不同的檔案組織,計算出來的BM25分數可能不一樣。 SELECT id, content, TEXT_SEARCH(content, '+shandong -physics famous', 'natural_language') as score FROM wiki_articles WHERE TEXT_SEARCH(content, '+shandong -physics famous', 'natural_language') > 0 ORDER BY score DESC; -- 返回結果 id | content | score ----+--------------------------------------------------+---------- 8 | ShanDa is a famous university of Shandong. | 2.92376 7 | Shandong has dozens of universities. | 0.863399 2 | Li was born in 1962 in Wendeng County, Shandong. | 0.716338 -- (N4) 自然語言查詢:短語檢索,與(P1)等價,短語需用雙引號""包裹,如果中間有",則需使用\轉義。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '"shandong university"', 'natural_language') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 3 | He graduated from the department of physics at Shandong University. -- (N5) 自然語言查詢:短語檢索,與(P2)等價,支援以~文法設定slop SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '"shandong university"~23', 'natural_language') > 0; -- 返回結果 id | content ----+--------------------------------------------------------------------- 8 | ShanDa is a famous university of Shandong. 7 | Shandong has dozens of universities. 3 | He graduated from the department of physics at Shandong University. -- (N6) 自然語言查詢:匹配所有文檔 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '*', 'natural_language') > 0; -- 返回結果 id | content ----+---------------------------------------------------------------------------------------------- 1 | 長江是中國第一大河,世界第三長河,全長約6,300公裡。 2 | Li was born in 1962 in Wendeng County, Shandong. 3 | He graduated from the department of physics at Shandong University. 4 | 春節,即農曆新年,是中國最重要的傳統節日。 5 | 春節通常在西曆1月下旬至2月中旬之間。春節期間的主要習俗包括貼春聯、放鞭炮、吃年夜飯、拜年等。 6 | 2006年,春節被國務院批准為第一批國家級非物質文化遺產。 7 | Shandong has dozens of universities. 8 | ShanDa is a famous university of Shandong. -
術語查詢。
-- (T1) 術語查詢:分詞結果中,有明確包含"春節",可以檢索到 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, '春節', 'term') > 0; -- 返回結果 id | content ----+---------------------------------------------------------------------------------------------- 4 | 春節,即農曆新年,是中國最重要的傳統節日。 5 | 春節通常在西曆1月下旬至2月中旬之間。春節期間的主要習俗包括貼春聯、放鞭炮、吃年夜飯、拜年等。 6 | 2006年,春節被國務院批准為第一批國家級非物質文化遺產。 -- (T2) 術語查詢:無法查詢到結果的樣本 -- 因為檢索源表wiki_articles列content預設使用jieba分詞器,會將"shandong university"拆分。 -- 推薦term術語查詢和keyword分詞器搭配,該情境即可檢索到目標資料。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university', 'term') > 0; -- 返回結果 id | content ----+---------
複雜查詢樣本
-
與PK聯集查詢。
-- 檢索源中包含shandong或university,且id=3的文本。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university') > 0 and id = 3; -- 返回結果 id | content ----+--------------------------------------------------------------------- 3 | He graduated from the department of physics at Shandong University. -- 檢索源中包含shandong或university,或id<2的文本。 SELECT * FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university') > 0 OR id < 2; -- 返回結果 id | content ----+--------------------------------------------------------------------- 2 | Li was born in 1962 in Wendeng County, Shandong. 8 | ShanDa is a famous university of Shandong. 1 | 長江是中國第一大河,世界第三長河,全長約6,300公裡。 3 | He graduated from the department of physics at Shandong University. 7 | Shandong has dozens of universities. -
查出分數,並取TOP3。
SELECT id, content, TEXT_SEARCH(content, 'shandong university') AS score, TOKENIZE(content, 'jieba') FROM wiki_articles ORDER BY score DESC LIMIT 3; -- 返回結果 id | content | score | tokenize ----+---------------------------------------------------------------------+---------+-------------------------------------------------- 8 | ShanDa is a famous university of Shandong. | 2.74634 | {shanda,famous,univers,shandong} 7 | Shandong has dozens of universities. | 2.74634 | {shandong,has,dozen,univers} 3 | He graduated from the department of physics at Shandong University. | 2.38178 | {he,graduat,from,depart,physic,shandong,univers} -
同時在output和where中使用TEXT_SEARCH函數。
SELECT id, content, TEXT_SEARCH(content, 'shandong university') AS score, TOKENIZE(content, 'jieba') FROM wiki_articles WHERE TEXT_SEARCH(content, 'shandong university') > 0 ORDER BY score DESC; -- 返回結果 id | content | score | tokenize ----+---------------------------------------------------------------------+---------+-------------------------------------------------- 7 | Shandong has dozens of universities. | 2.74634 | {shandong,has,dozen,univers} 8 | ShanDa is a famous university of Shandong. | 2.74634 | {shanda,famous,univers,shandong} 3 | He graduated from the department of physics at Shandong University. | 2.38178 | {he,graduat,from,depart,physic,shandong,univers} 2 | Li was born in 1962 in Wendeng County, Shandong. | 1.09244 | {li,born,1962,wendeng,counti,shandong} -
檢索wiki來源中,和shandong university最相關的文檔。
-- 來源表,用於JOIN。 CREATE TABLE article_source (id int primary key, source text); INSERT INTO article_source VALUES (1, 'baike'), (2, 'wiki'), (3, 'wiki'), (4, 'baike'), (5, 'baike'), (6, 'baike'), (7, 'wiki'), (8, 'paper'), (9, 'http_log'), (10, 'http_log'), (11, 'http_log'); SELECT a.id, source, content, TEXT_SEARCH(content, 'shandong university') AS score, TOKENIZE(a.content, 'jieba') FROM wiki_articles a JOIN article_source b ON (a.id = b.id) WHERE TEXT_SEARCH(a.content, 'shandong university') > 0 AND b.source = 'wiki' ORDER BY score DESC; -- 返回結果 id | source | content | score | tokenize ----+--------+---------------------------------------------------------------------+---------+-------------------------------------------------- 7 | wiki | Shandong has dozens of universities. | 2.74634 | {shandong,has,dozen,univers} 3 | wiki | He graduated from the department of physics at Shandong University. | 2.38178 | {he,graduat,from,depart,physic,shandong,univers} 2 | wiki | Li was born in 1962 in Wendeng County, Shandong. | 1.09244 | {li,born,1962,wendeng,counti,shandong}
使用建議
使用Serverless資源重建索引
如果表屬性修改,可能觸發Compaction並重建索引,帶來大量CPU消耗。如有下列表屬性修改需求,建議按下文步驟操作:
修改bitmap_columns、dictionary_encoding_columns、向量索引,均會觸發Compaction並重建索引,因此不建議使用ALTER TABLE xxx SET文法修改,建議執行如下命令,通過Rebuild文法、使用Serverless Computing資源執行,詳情參見REBUILD。
ASYNC REBUILD TABLE <table_name>
WITH (
rebuild_guc_hg_computing_resource = 'serverless'
)
SET (
bitmap_columns = '<col1>,<col2>',
dictionary_encoding_columns = '<col1>:on,<col2>:off',
vectors = '{
"<col_vector>": {
"algorithm": "HGraph",
"distance_method": "Cosine",
"builder_params": {
"base_quantization_type": "rabitq",
"graph_storage_type": "compressed",
"max_degree": 64,
"ef_construction": 400,
"precise_quantization_type": "fp32",
"use_reorder": true,
"max_total_size_to_merge_mb" : 4096
}
}
}'
);修改列式JSONB列、全文索引列,也會觸發Compaction並重建索引,暫不支援通過Rebuild文法執行,建議通過建立暫存資料表方案修改,詳見如下步驟:
BEGIN ;
-- 清理潛在的暫存資料表
DROP TABLE IF EXISTS <table_new>;
-- 建立暫存資料表
SET hg_experimental_enable_create_table_like_properties=on;
CALL HG_CREATE_TABLE_LIKE ('<table_new>', 'select * from <table>');
COMMIT ;
-- 對應列開啟列式JSONB
ALTER TABLE <table_new> ALTER COLUMN <column_name> SET (enable_columnar_type = ON);
-- 對應列建立全文索引
CREATE INDEX <idx_name> ON <table_new> USING FULLTEXT (column_name);
-- 向暫存資料表插入資料,使用Serverless資源執行,並同步完成索引構建
SET hg_computing_resource = 'serverless';
INSERT INTO <table_new> SELECT * FROM <table>;
ANALYZE <table_new>;
BEGIN ;
-- 刪除舊錶
DROP TABLE IF EXISTS <table>;
-- 暫存資料表改名
ALTER TABLE <table_new> RENAME TO <table>;
COMMIT ;修改其他屬性,如distribution_key、clustering_key、segment_key、儲存格式等,均建議通過Rebuild文法、使用Serverless Computing資源執行。
進階操作:自訂分詞器配置
Hologres建議使用分詞器的預設配置,但在全文倒排索引的實際使用過程中,可能出現分詞器預設配置不滿足業務需求的情況。您可自訂分詞器配置,以滿足業務更靈活的分詞需要。
analyzer_params配置要求
分詞器配置參數analyzer_params的配置要求如下:
-
僅支援JSON格式字串。
-
JSON頂層支援tokenizer、filter兩個鍵,取值如下:
-
filter:選填,值為JSON數組,用於配置分詞過濾屬性。如需配置多個分詞過濾屬性,將嚴格遵循配置順序作用到每一個分詞token上。
-
tokenizer:必填,值為JSON對象,用於配置分詞器屬性。JSON對象中支援如下鍵:
-
type:必填,分詞器名稱
-
tokenizer對象的其他參數,不同分詞器支援的參數不同,詳見下表:
分詞器
tokenizer對象
的其他參數參數說明
參數取值
jieba
mode
定義分詞模式。
-
search(預設):分詞時列舉多種可能的組合,允許冗餘。如“傳統節日”的分詞結果為“傳統”、“節日”和“傳統節日”共3個token。
-
exact:分詞時不冗餘切分。如“傳統節日”的分詞結果僅為“傳統節日”1個token。
hmm
定義是否使用隱馬爾可夫模型來識別詞典中沒有的詞,以提高新詞識別能力。
-
true(預設):使用
-
false:不使用
standard
max_token_length
最大token長度。
正整數,預設值255。如果遇到超過此長度的token,則會以 max_token_length 為間隔進行拆分。
ik
mode
定義分詞模式。
-
ik_max_word(預設):細粒度分詞,輸出所有可能的短詞。如“南京市”的分詞結果為“南京”和“市”。
-
ik_smart:粗粒度分詞,優先輸出長詞,減少切分數量。分詞輸出的token之間不會產生重疊。會嘗試將數詞和量片語合,作為一個token輸出。如“南京市”、“1千米”均不繼續分詞。
enable_lowercase
是否將Token轉換成小寫。
-
true(預設)
-
false
ngram
min_ngram
Token最小字元長度。
預設為1。正數。與max_ngram差距最大為3。
說明:可通過設定如下GUC,調整最大差距值,如
SET hg_fulltext_index_max_ngram_diff = 5max_ngram
Token最大字元長度。
預設為2。取值範圍[1, 255]。與min_ngram差距最大為3。
說明當max_ngram與min_ngram差距過大時,ngram分詞器會產生大量分詞token,導致資源消耗增大、索引儲存增加、索引構建時間長度增加等問題。
prefix_only
是否只考慮首碼。
-
true
-
false(預設)
pinyin
keep_first_letter
是否保留每個漢字的首字母。
-
true(預設):保留。如“李明”分詞結果包含“lm”。
-
false:不保留。
keep_separate_first_letter
是否單獨保留每個漢字的首字母。
-
true:保留。如“李明”分詞結果包含“l,m”。
-
false(預設):不保留。
limit_first_letter_length
首字母結果Token的最大長度。
保留的首字母串的最大長度。Int類型,預設為16。
keep_full_pinyin
是否保留每個漢字的完整拼音。
-
true(預設):保留。如“李明”分詞結果包含“li,ming”。
-
false:不保留。
keep_joined_full_pinyin
是否串連每個漢字的完整拼音。
-
true:串連。如“李明”分詞結果包含“liming”。
-
false(預設):不串連。
keep_none_chinese
是否保留結果中的非漢字字母或數字。
-
true(預設):保留。
-
false:不保留。
keep_none_chinese_together
是否將非漢字字母或數字保留在一起。
-
true(預設):保留。如“DJ李明”分詞結包含“DJ,li,ming”,“DJ”串連在一起。
-
false:不保留如“DJ李明”分詞結果包含“D,J,li,ming”。
說明該參數需將keep_none_chinese設為true才生效。
keep_none_chinese_in_first_letter
是否在首字母Token中保留非漢字字母或數字。
-
true(預設):保留。如“李明AT2025”分詞結果包含“lmat2025”。
-
false:不保留。
keep_none_chinese_in_joined_full_pinyin
是否在完整拼音串連的Token中保留非漢字字母或數字。
-
true:保留。如“李明AT2025”分詞結果包含“limingat2025”。
-
false(預設):不保留。
none_chinese_pinyin_tokenize
如果非漢字字母是拼音,是否拆分為單獨的拼音詞項。
-
true(預設):拆分。如“limingalibaba2025”分詞結果包含“li,ming,a,li,ba,ba,2025”
-
false:不拆分
說明該參數需將keep_none_chinese、keep_none_chinese_together設為true才生效。
keep_original
是否保留原始輸入。
-
true:保留
-
false(預設):不保留
lowercase
是否將非漢字字母小寫化處理。
-
true(預設)
-
false
trim_whitespace
是否裁剪空白字元。
-
true(預設)
-
false
remove_duplicated_term
是否移除重複詞項。
-
true,移除。如“de的”分詞結果為“de”,但會影響對“de的”的短語查詢結果。
-
false(預設),不移除。
keep_separate_chinese
是否保留單獨漢字。
-
true:保留。如“李明”分詞結果包含“李,明”2個Token。
-
false(預設):不保留。
-
-
-
analyzer_params預設配置
不同分詞器對應的analyzer_params預設配置如下:
|
分詞器名稱 |
analyzer_params預設配置 |
分詞樣本 |
|
jieba(預設分詞器) |
|
|
|
whitespace |
|
|
|
keyword |
|
|
|
simple |
|
|
|
standard |
|
|
|
icu |
|
|
|
ik |
|
|
|
ngram |
|
|
|
pinyin |
|
|
analyzer_params中的filter配置
Hologres支援在analyzer_params中配置如下filter(分詞過濾屬性)。
如果配置了多個分詞過濾屬性,將嚴格遵循配置順序作用到每一個分詞token上。
|
屬性名稱 |
屬性說明 |
參數格式 |
使用樣本 |
|
lowercase |
將token中的大寫字母轉為小寫。 |
僅需聲明lowercase。
|
|
|
stop |
移除停用詞token。 |
|
|
|
stemmer |
根據對應語言的文法規則,將token轉化為其對應的詞幹。 |
|
|
|
length |
移除超過指定長度的token。 |
|
|
|
removepunct |
移除只包含標點符號字元的token。 |
僅需聲明removepunct。
說明
自4.0.8開始, removepunct新增mode參數,定義移除模式,取值如下:
|
|
|
pinyin |
拼音Token Filter。 |
|
Filter配置屬性同Pinyin分詞器。 |