OceanBaseデータベースのMySQLモードでは、フルテキストインデックスはCHAR、VARCHAR、およびTEXT型の列に適用できます。さらに、OceanBaseデータベースでは、メインテーブルに複数のフルテキストインデックスを作成することができ、同一列に対しても複数のフルテキストインデックスを作成できます。
パーティションテーブルとパーティションテーブルの両方に主キーがある場合でも、フルテキストインデックスを作成できます。ただし、フルテキストインデックスの作成には以下の制限があります:
- フルテキストインデックスは
CHAR、VARCHAR、およびTEXT型の列にのみ適用できます。 - 現在のバージョンでは、ローカル(
LOCAL)フルテキストインデックスの作成のみサポートされています。 - フルテキストインデックスを作成する際には、
UNIQUEキーワードを指定することはできません。 - 複数の列にまたがるフルテキストインデックスを作成する場合は、これらの列が同じ文字セットを持っていることを確認する必要があります。
これらの構文とルールを使用することで、OceanBaseデータベースのフルテキストインデックス機能は、テキストデータに対する効率的な検索と取得機能を提供します。
DML操作
全文インデックスを含むテーブルが作成されている場合、INSERT INTO ON DUPLICATE KEY、REPLACE INTO、複数テーブルの更新・削除、および更新可能なビューなどの複雑なDML操作をサポートします。
例:
INSERT INTO ON DUPLICATE KEY:
INSERT INTO articles VALUES ('OceanBase', 'Fulltext search index support insert into on duplicate key') ON DUPLICATE KEY UPDATE title = 'OceanBase 4.3.3';REPLACE INTO:
REPLACE INTO articles(title, context) VALUES ('Oceanbase 4.3.3', 'Fulltext search index support replace');複数テーブルの更新・削除。
テーブル
tbl1を作成します。CREATE TABLE tbl1 (a int PRIMARY KEY, b text, FULLTEXT INDEX(b));テーブル
tbl2を作成します。CREATE TABLE tbl2 (a int PRIMARY KEY, b text);複数テーブルの更新(
UPDATE)ステートメント。UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl1.b = 'dddd', tbl2.b = 'eeee';UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl1.b = 'dddd';UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl2.b = tbl1.b;複数テーブルの削除(
DELETE)ステートメント。DELETE tbl1, tbl2 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;DELETE tbl1 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;DELETE tbl1 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;
更新可能なビューのDML。
ビュー
fts_viewを作成します。CREATE VIEW fts_view AS SELECT * FROM tbl1;更新可能なビューには
INSERTステートメントを使用します。INSERT INTO fts_view VALUES(3, 'cccc'), (4, 'dddd');更新可能なビューには
UPDATEステートメントを使用します。UPDATE fts_view SET b = 'dddd';UPDATE fts_view JOIN normal ON fts_view.a = tbl2.a SET fts_view.b = 'dddd', tbl2.b = 'eeee';更新可能なビューには
DELETEステートメントを使用します。DELETE FROM fts_view WHERE b = 'dddd';DELETE tbl1 FROM fts_view JOIN tbl1 ON fts_view.a = tbl1.a AND 1 = 0;
フルテキストインデックスのパーサー
OceanBaseのフルテキストインデックス機能は、複数の組み込みパーサーをサポートしており、ユーザーがビジネスシナリオに応じて最適なテキスト分割戦略を選択できるようにします。デフォルトのパーサーはSpaceパーサーであり、他のパーサーはWITH PARSERパラメータで明示的に指定する必要があります。
パーサーリスト:
- Spaceパーサー
- Basic Englishパーサー
- IKパーサー (V4.3.5 BP1バージョンから
IKパーサーがサポートされています。) - Ngramパーサー (V4.3.5 BP2バージョンから
NGRAM2パーサーがサポートされています。) - jiebaパーサー
設定方法の例:
テーブルの作成または変更時に、CREATE TABLE/ALTER TABLEステートメントを使用してテーブルにフルテキストインデックスを作成する際に、パラメータWITH PARSER tokenizer_optionを設定し、フルテキストインデックスのパーサータイプを指定します。その他のパーサーのプロパティパラメータの設定については、インデックスの作成を参照してください。
CREATE TABLE tbl2(id INT, name VARCHAR(18), doc TEXT,
FULLTEXT INDEX full_idx1_tbl2(name, doc)
WITH PARSER NGRAM
PARSER_PROPERTIES=(ngram_token_size=3));
-- 既存テーブルのフルテキストインデックスのパーサーを変更
ALTER TABLE tbl2(id INT, name VARCHAR(18), doc TEXT,
FULLTEXT INDEX full_idx1_tbl2(name, doc)
WITH PARSER NGRAM
PARSER_PROPERTIES=(ngram_token_size=3)); -- Ngramの例
スペース分割器(デフォルト)
概念:
- テキストをスペース、句読点(カンマ、ピリオドなど)、またはアルファベット・数字以外の文字(アンダースコア
_を除く)を区切り文字として分割します。 - 分割結果には、長さが
min_token_size(デフォルトは3)からmax_token_size(デフォルトは84)の間の有効な単語要素のみが含まれます。 - 中国語の文字は個別の文字として扱われます。
適用シナリオ:
- スペースで区切られる言語(例:「apple watch series 9」)。
- 中国語で手動で区切り文字を追加する場合(例:「南京 長江大橋」)。
分割結果:
OceanBase (rooteoceanbase) >select tokenize ("南京市长江大桥有1千米长,详见www.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'space');
+-------------------------------------------------------------------------------------------------------------+
| tokenize ("南京市长江大桥有1千米长,详见www.XXX.COM, 邮箱xx@OB.COM,一平方公里也很小 hello-word h_name", 'space') |
+-------------------------------------------------------------------------------------------------------------+
|["详见www", "一平方公里也很小", "xxx", "南京市长江大桥有1千米长", "邮箱xx", "word", "hello”, "h_name"] |
+-------------------------------------------------------------------------------------------------------------+
例:
- スペース、カンマ、ピリオドなどの記号が区切り文字として使用され、中国語の連続した文字は単語として扱われます。
Basic English(Beng)分割器
概念:
- スペース分割器と似ていますが、アンダースコア
_は保持せず、それを区切り文字として扱います。 - 英語のフレーズの区切りに適していますが、スペースのない用語(例:「iPhone15」)の分割効果は限られています。
適用シナリオ:
- 英語ドキュメントの基本的な検索(ログ、コメントなど)。
分割結果:
OceanBase (rooteoceanbase) >select tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'beng');
+-----------------------------------------------------------------------------------------------------------------------+
| tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM,邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'beng') |
+-----------------------------------------------------------------------------------------------------------------------+
|["详见www", "一平方公里也很小", "xxx", "南京市长江大桥有1千米长", "邮箱xx", "word", "hello", "name"] |
+-----------------------------------------------------------------------------------------------------------------------+
例:
- アンダースコア
_は分割されますが、スペース分割器との主な違いは_の処理方法にあります。
Ngram形態素解析器
概念:
- 固定n値の形態素解析:デフォルトでは
n=2であり、連続する区切り文字以外の文字を長さがnのサブシーケンスに分割します。 - 区切り文字の判定ルールはSpace形態素解析器と同じです(アンダースコアと数字・英字は保持されます)。
- 長さ制限パラメータはサポートされていません。出力されるのは、すべての可能な長さ
nの語素です。
適用シナリオ:
- 短いテキストのあいまい一致(ユーザーID、注文番号など)。
- 固定長の特徴抽出が必要なシナリオ(パスワードポリシー分析など)。
形態素解析結果:
OceanBase (rooteoceanbase) >select tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'ngram');
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'ngram') |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["邮箱", "ww", "大桥", “ob", "me", "里也", "or", "_n", "千米", "很小", "米长", "ll", "箱x", "公里", "见w", "co", "也很", "1千", "京市", "lo", "江大", "el", "rd", "一平", "方公", "he", "am", "南京", "h_", "市长", "wo", "xx", "长江", "有1", "na", "详见", "平方", "om", "桥有" |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
例の説明:
- デフォルトの
n=2の場合、重複部分を含むすべての連続する2文字の語素が出力されます。
Ngram2 分かち書き
概念:
- 動的なn値範囲をサポートします:
min_ngram_sizeとmax_ngram_sizeパラメータで、語長の範囲を設定できます。 - 複数の長さの語をカバーする必要があるシナリオに適しています。
適用シナリオ:複数の固定長の語を同時に必要とするシナリオ。
説明
ngram2分かち書きを使用する場合、メモリ使用量が高くなることに注意する必要があります。例えば、min_ngram_size と max_ngram_size パラメータの範囲を広く設定すると、大量の語の組み合わせが生成され、リソース消費が過剰になる可能性があります。
分かち書きの効果:
OceanBase (rooteoceanbase) >select tokenize ("南京市长江大桥1千米", 'ngram2', '[{"additional_args":[{"min_ngram_size": 4},{"max_ngram_size": 6}]}]');
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥1千米", 'ngram2', '[{"additional_args":[{"min_ngram_size": 4},{"max_ngram_size": 6}]}]') |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["长江大桥", "大桥1千", "江大桥1千", "市长江大桥", "京市长江", "江大桥1", "南京市长", "市长江大", "大桥1千米", "江大桥1千米", "市长江大桥1", "长江大桥1", "南京市长江", "桥1千米", "南京市长江大", "长江大桥1千", "京市长江大桥", "京市长江大" |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
例の説明:
- 出力長は4~6文字のすべての連続部分列であり、語は重複可能です。
IK形態素解析器
概念:
オープンソースツールIK Analyzerに基づく中国語の形態素解析器で、2つのモードをサポートしています:
- スマートモード:長い単語を優先的に出力し、分割数を減らします(例えば、「南京市」は「南京」「市」とは分割されません)。
- Max Wordモード:すべての可能な短い単語を出力します(例えば、「南京市」は「南京」「市」と分割されます)。
英単語、メールアドレス、URL(
://を除く)、IPアドレスなどの形式を自動的に識別します。
適用シナリオ:中国語の形態素解析
ビジネスシナリオ:
Eコマース商品説明の検索(例えば、「華為Mate60」の正確なマッチング)。
ソーシャルメディアコンテンツの分析(例えば、ユーザーのコメントからキーワードを抽出する)。
スマートモード:1文字が1つの語にのみ属し、重複がなく、単一の語を構成する長さをできるだけ長く、構成する語をできるだけ少なくすることを保証します。数詞と量詞を組み合わせて、1つの語として出力するよう試みます。
OceanBase (rooteoceanbase) >select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM 192.168.1.1 http://www.baidu.com hello-word hello_word", 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]');
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM 192.168.1.1 http://www.baidu.com hello-word hello_word", 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]') |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["邮箱", "hello_word", "192.168.1.1", "hello-word", "长江大桥", "www.baidu.com", "www.xxx.com", "xx@ob.com", "长", "http", "1千米", "详见", "南京市", "有"] |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
- max_wordモード:同じ文字を異なる形態素に含め、可能な限り多くの語を提供します。
OceanBase (rooteoceanbase) >select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM", 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]');
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM", 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]') |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["米", "长江大桥", "市长", "干", "南京市", "南京", "千米", "xx", "www.xxx.com", "长", "www", "xx@ob.com", "长江", "ob", "XXX", "com", "详见", "l", "有", "大桥", "邮箱"] |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
jieba 分詞器
概念:Pythonエコシステムのオープンソースツール jieba を基にした分詞器で、高精度モード、フルモード、検索エンジンモードをサポートしています。
特徴:
- 高精度モード:辞書に厳密に従って単語を分割します(例えば、「不能」は「不」「能」とは分割されません)。
- フルモード:可能なすべての分割パターンをリストアップします。
- 検索エンジンモード:精度と再現率のバランスを取ります(例えば、「南京長江大橋」→「南京」「市長」「長江大橋」)。
- カスタム辞書と新語の検出をサポートし、複数の言語(中国語、英語、日本語など)に対応しています。
適用シナリオ:
- 医療・科学技術分野の専門用語分析(例えば、「人工知能」を高精度に分割する)。
- 複数言語が混在するテキスト処理(例えば、中国語と英語が混在するソーシャルメディアコンテンツ)。
jieba分詞器プラグインは、お客様自身でインストールおよびコンパイルする必要があります。詳細な手順については、分詞器プラグインを参照してください。
注意
- OceanBaseデータベースV4.3.5では、V4.3.5 BP1以降のバージョンから分詞器プラグインがサポートされています。
- 現在の分詞器プラグインは実験的機能であり、本番環境での使用は推奨されません。
分詞器選択ポリシー
| ビジネスシナリオ | 推奨する形態素解析器 | 理由 |
|---|---|---|
| 英語の商品タイトル検索 | SpaceまたはBasic English | シンプルで効率的、英語の形態素解析習慣に合致しています。 |
| 中国語の商品説明の検索 | IK形態素解析器 | 中国語の専門用語を正確に識別し、カスタム辞書をサポートします。 |
| ログのあいまい一致(エラーコードなど) | Ngram形態素解析器 | 辞書不要、スペースのないテキストのあいまいクエリニーズをカバーします。 |
| 科学論文のキーワード抽出 | jieba形態素解析器 | 新語の発見と複雑なパターンの切り替えをサポートします。 |
関連ドキュメント
全文インデックスの作成に関する詳細は、インデックスの作成 の 全文インデックスの作成 セクションを参照してください。