転置インデックスは、情報検索における一般的なインデックス技術です。テキストをトークン化してタームに変換し、インデックスを構築することで、それらのタームを含むドキュメントを迅速に取得できます。ApsaraDB for SelectDB は転置インデックスをサポートしています。この機能を使用することで、テキストデータ型の全文検索や、数値および日付データ型の等価クエリおよび範囲クエリを実行でき、大規模なデータセットから特定のデータを迅速にフィルターできます。このトピックでは、ApsaraDB for SelectDB の転置インデックス機能について、その作成方法と使用方法を含めて説明します。
仕組み
Alibaba Cloud SelectDB では、転置インデックスはテーブルの行をドキュメントとして、列をフィールドとして扱います。これにより、転置インデックスは特定のキーワードを含む行を迅速に特定できるようになり、WHERE 句を使用するクエリのパフォーマンスが向上します。
通常のインデックスとは異なり、転置インデックスは独立した転置ファイルに保存されます。このファイルは論理的にセグメントファイルにマッピングされていますが、統合はされていません。このアプローチにより、インデックスの更新や削除時にセグメントファイルを書き換える必要がなくなり、処理オーバーヘッドが大幅に削減されます。
シナリオ
-
文字列データ型の全文検索を高速化します。
-
文字列型、数値型、および日時型での
=, !=, >, >=, <, <=によるフィルタリングを高速化します。
メリット
-
論理演算子の包括的なサポート。
-
OR と NOTロジックのインデックスプッシュダウンをサポートするようになりました。 -
複数の条件による
AND、OR、NOTの任意の組み合わせをサポートしています。
-
-
柔軟で高速なインデックス管理。
-
テーブルの作成時に転置インデックスを作成します。
-
既存のテーブルに転置インデックスを追加します。
-
テーブルから転置インデックスを削除します。
-
制限事項
-
FLOATおよびDOUBLE浮動小数点データ型は、精度に問題があるため転置インデックスをサポートしていません。代わりに、転置インデックスをサポートするDECIMAL固定小数点データ型を使用してください。 -
一部の複合データ型は転置インデックスをサポートしていません。これには、
MAP、STRUCT、JSON、HLL、BITMAP、QUANTILE_STATE、およびAGG_STATEなどが含まれます。JSONデータで転置インデックスを使用するには、列をVARIANTデータ型に変換してください。 -
数値型のフィールドに転置インデックスを作成できますが、
parser(english、chinese、unicodeなど) を指定することはできません。 -
DUPLICATEモデル、およびマージオンライトが有効なUNIQUEモデルは、任意の列で転置インデックスをサポートしています。一方、AGGREGATEモデル、およびマージオンライトが無効なUNIQUEモデルでは、キー列でのみ転置インデックスをサポートしています。これらのモデルでは、すべてのデータを読み取ってマージする必要があるため、システムは事前フィルタリングにインデックスを使用できません。
インデックスの作成
転置インデックスは、テーブル作成時に作成するか、既存テーブルの列に対して作成することができます。
テーブル作成時のインデックス作成
同期操作です。インデックスの作成は、テーブルが正常に作成されると完了します。
転置インデックスには、データモデルごとに以下の制限事項があります。
-
Aggregate Key モデルの場合、転置インデックスはキー列にのみ作成できます。
-
Unique Key モデルの場合、Merge on Write 機能を有効にする必要があります。有効にすると、任意の列に転置インデックスを作成できます。
-
Duplicate Key モデルの場合、任意の列に転置インデックスを作成できます。
構文
CREATE TABLE [IF NOT EXISTS] [db_name.]<table_name>
(
<column_definition_list>,
[<index_definition_list>]
)
table_properties;
パラメータ
テーブル作成パラメータ
|
パラメータ |
必須 |
説明 |
|
db_name |
任意 |
テーブルを含むデータベースの名前。 |
|
table_name |
必須 |
作成するテーブルの名前。 |
|
column_definition_list |
必須 |
列定義のリスト。詳細については、「CREATE-TABLE」をご参照ください。 |
|
table_properties |
必須 |
データモデル、パーティショニング、バケット化などのテーブルプロパティ。詳細については、「データモデル」をご参照ください。 |
|
index_definition_list |
任意 |
インデックス定義のリスト。 |
index_definition_list
テーブルを作成するときに、1 つ以上のインデックスを定義できます。次の形式を使用します: index_definition[, index_definition][, index_definition]...。
index_definition
INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")] [COMMENT '<comment>']
パラメータ
必須パラメータ
|
パラメータ |
説明 |
|
index_name |
インデックスの名前。 |
|
column_name |
インデックスを作成する列の名前。 |
|
index_type |
インデックスタイプ。これを |
任意パラメータ
プロパティ
PROPERTIES 句は、インデックスのトークン化オプションを指定します。これは、"<key>" = "<value>" の形式でカンマで区切られた 1 つ以上のキーと値のペアで構成されています。特定のテキストがどのようにトークン化されるかわからない場合は、TOKENIZE 関数を使用して出力を表示します。詳細については、「トークン化関数」をご参照ください。
|
キー |
値 |
|
parser |
トークナイザーを指定します。このプロパティを省略すると、トークン化は行われません。
|
|
parser_mode |
単語のトークン化モードを指定します。これにより、トークン化の粒度が決まります。 すべてのトークナイザーは、デフォルトで coarse_grained モードを使用します。このモードは、テキストをより長い単語に分割する傾向があります。たとえば、 中国語トークナイザーで トークン化の仕組みの詳細については、「トークン化関数」をご参照ください。 |
|
support_phrase |
インデックスが高速化された
|
|
char_filter |
トークン化の前に文字列を前処理します。現在、
|
|
ignore_above |
トークン化されていない文字列値 (
|
|
lower_case |
大文字と小文字を区別しないマッチングのために、トークン化されたタームを小文字に変換するかどうかを指定します。
|
|
stopwords |
ストップワードのリストを指定します。これはトークナイザーの動作に影響します。
|
|
dict_compression |
転置インデックスの辞書に対して Zstandard (ZSTD) 辞書圧縮を有効にするかどうかを指定します。
説明
このパラメータは、バージョン 4.1.0 以降でのみサポートされています。 |
コメント
|
パラメータ |
説明 |
|
comment |
インデックスの説明。 |
例: インデックスを持つテーブルの作成
-- テーブルを作成し、comment 列に idx_comment という名前の転置インデックスを作成します。
-- USING INVERTED は、インデックスタイプを転置インデックスに設定します。
-- PROPERTIES("parser" = "english") は、トークナイザーを "english" に設定します。他のサポートされているトークナイザーには、中国語テキスト用の "chinese" や、多言語が混在するテキスト用の "unicode" があります。"parser" プロパティを省略すると、トークン化は行われません。
CREATE TABLE hackernews_1m
(
`id` BIGINT,
`deleted` TINYINT,
`type` String,
`author` String,
`timestamp` DateTimeV2,
`comment` String,
`dead` TINYINT,
`parent` BIGINT,
`poll` BIGINT,
`children` Array<BIGINT>,
`url` String,
`score` INT,
`title` String,
`parts` Array<INT>,
`descendants` INT,
INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'inverted index for comment'
)
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10;
インデックスの追加
このオペレーションは非同期オペレーションです。インデックス作成の進捗は、SHOW ALTER TABLE COLUMN; を使用して確認できます。
構文
ALTER TABLE <table_name> ADD INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")];
パラメータ
パラメータは、テーブル作成時と同じです。
例
トークン化なしでインデックスを追加します。
ALTER TABLE user_tb ADD INDEX index_userId(user_id) USING INVERTED ;
トークン化に english を使用するインデックスを追加します。
ALTER TABLE user_tb ADD INDEX index_city(city) USING INVERTED PROPERTIES("parser" = "english");
転置インデックスの表示
インデックス変更の進捗の表示
ALTER コマンドと DROP コマンドを使用した転置インデックスの変更は、非同期プロセス です。進捗を表示するには、次のステートメントを使用します。
SHOW ALTER TABLE COLUMN;
テーブル内のすべてのインデックスの表示
構文
SHOW INDEXES FROM <table_name>;
例
SHOW INDEXES FROM user_tb;
インデックスの削除
インデックスの削除は非同期プロセスです。進行状況を確認するには、「転置インデックス情報のクエリ」 をご参照ください。
インデックスを削除すると、クエリパフォーマンスが低下する可能性があります。慎重に実行してください。
構文
-- 構文 1
DROP INDEX <index_name> ON <table_name>;
-- 構文 2
ALTER TABLE <table_name> DROP INDEX <index_name>;
例
DROP INDEX index_userId ON user_tb;
ALTER TABLE user_tb DROP INDEX index_city;
転置インデックス
全文検索
構文
SELECT * FROM <table_name> WHERE <column_name> <conditional_logic> '<keywords>';
パラメーター
|
パラメーター |
必須 |
説明 |
|
table_name |
はい |
テーブルの名前です。 |
|
column_name |
はい |
カラムの名前です。 |
|
conditional_logic |
はい |
検索演算子と論理演算子の組み合わせです。 論理演算子: 検索演算子:
|
|
keywords |
はい |
検索キーワードです。 複数のキーワードはスペースで区切ります。 例: |
例
-- logmsg に keyword1 を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';
-- logmsg に keyword1 または keyword2 を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';
-- logmsg に keyword1 と keyword2 の両方を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';
-- logmsg に正確なフレーズ "keyword1 keyword2" を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';
数値と日付に対する等価クエリと範囲クエリ
クエリ構文は標準 SQL 構文です。
例
-- 等価、範囲、IN クエリ
SELECT * FROM user_tb WHERE id = 123;
SELECT * FROM user_tb WHERE ts > '2023-01-01 00:00:00';
SELECT * FROM user_tb WHERE op_type IN ('add', 'delete');
クエリパフォーマンスの比較
このトピックでは、100 万行の hackernews データセットを使用して、転置インデックスの有無によるクエリパフォーマンスを比較します。
前提条件
ステップ 1:テーブルを作成します。
-
データベースを作成します。
CREATE DATABASE test_inverted_index; -
作成したデータベースに切り替えます。
USE test_inverted_index; -
対象テーブルを作成します。
CREATE TABLE hackernews_1m ( `id` BIGINT, `deleted` TINYINT, `type` String, `author` String, `timestamp` DateTimeV2, `comment` String, `dead` TINYINT, `parent` BIGINT, `poll` BIGINT, `children` Array<BIGINT>, `url` String, `score` INT, `title` String, `parts` Array<INT>, `descendants` INT, INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'inverted index for comment' ) DUPLICATE KEY(`id`) DISTRIBUTED BY HASH(`id`) BUCKETS 10; -- テーブルを作成し、comment 列に idx_comment という名前の転置インデックスを作成します。 -- USING INVERTED は、インデックスタイプが転置インデックスであることを指定します。 -- PROPERTIES("parser" = "english") は、英語トークナイザーを使用することを指定します。中国語テキストの場合は "chinese"、複数言語が混在するテキストの場合は "unicode" を指定することもできます。"parser" パラメーターを指定しない場合、トークン化は実行されません。
ステップ 2:データをインポートします。
-
データファイルをダウンロードします。
wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz -
Stream Load を使用してデータをインポートします。
ApsaraDB for SelectDB のインスタンス詳細ページで、ApsaraDB for SelectDB インスタンスのエンドポイントホストとポート番号を確認できます。Stream Load の詳細については、Stream Load をご参照ください。
curl --location-trusted -u root: -H "compress_type:gz" -T hacknernews_1m.csv.gz http://<host>:<port>/api/test_inverted_index/hackernews_1m/_stream_load { "TxnId": 2, "Label": "a8a3e802-2329-49e8-912b-04c800a461a6", "TwoPhaseCommit": "false", "Status": "Success", "Message": "OK", "NumberTotalRows": 1000000, "NumberLoadedRows": 1000000, "NumberFilteredRows": 0, "NumberUnselectedRows": 0, "LoadBytes": 130618406, "LoadTimeMs": 8988, "BeginTxnTimeMs": 23, "StreamLoadPutTimeMs": 113, "ReadDataTimeMs": 4788, "WriteDataTimeMs": 8811, "CommitAndPublishTimeMs": 38 } -
count()クエリを実行して、データインポートを確認します。SELECT count() FROM hackernews_1m; +---------+ | count() | +---------+ | 1000000 | +---------+ 1 row in set (0.02 sec)
パフォーマンスの比較
-
トークナイザー付きの転置インデックスを使用するクエリと使用しないクエリでは、カウント結果が異なる場合があります。これは、転置インデックスが列データをトークン化し、ターム (例:小文字への変換) を正規化するため、インデックスを使用するクエリがより多くの行に一致する可能性があるためです。
-
一部の例では、データセットが小さいため、パフォーマンスの差が顕著でない場合があります。データセットが大きくなるほど、パフォーマンスの向上が大きくなります。
全文検索
-
comment列にOLAPが含まれる行数をカウントします。-
LIKE演算子を使用してcomment列でOLAPを含む行数をカウントすると、0.18 秒かかります。SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%'; +---------+ | count() | +---------+ | 34 | +---------+ 1 row in set (0.18 sec) -
転置インデックスに基づく
MATCH_ANY全文検索は、comment 列でOLAPを含む行数を 0.02 秒でカウントします。これは、LIKE 演算子を使用する場合よりも 9 倍高速です。SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP'; +---------+ | count() | +---------+ | 35 | +---------+ 1 行 (0.02 秒)
-
-
commentカラムにOLTPが含まれる行をカウントします。-
この操作は、LIKE 演算子を使用して、
commentカラムでOLTPを含む行数をカウントし、0.07 秒かかります。SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%'; +---------+ | count() | +---------+ | 48 | +---------+ 1 row in set (0.07 sec) -
転置インデックスに基づく
MATCH_ANY全文検索は、comment列でOLTPを含む行数を 0.01 秒でカウントします。これはLIKE演算子を使用する場合よりも 7 倍高速です。SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP'; +---------+ | count() | +---------+ | 51 | +---------+ 1 row in set (0.01 sec)
-
-
comment列にOLAPとOLTPの両方が含まれる行数をカウントします。-
LIKEを使用すると、クエリは 0.13 秒かかります。SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%'; +---------+ | count() | +---------+ | 14 | +---------+ 1 row in set (0.13 sec) -
MATCH_ALLを使用した全文検索では、クエリの所要時間は 0.01 秒となり、LIKEを使用する場合より 13 倍高速です。SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP'; +---------+ | count() | +---------+ | 15 | +---------+ 1 row in set (0.01 sec)
-
-
comment列にOLAPまたはOLTPのいずれかが含まれている行数をカウントします。-
LIKEを使用すると、クエリは 0.12 秒かかります。SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%'; +---------+ | count() | +---------+ | 68 | +---------+ 1 row in set (0.12 sec) -
MATCH_ANYによる全文検索を使用すると、クエリは 0.01 秒で完了し、LIKEを使用する場合の 12 倍高速です。SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP OLTP'; +---------+ | count() | +---------+ | 71 | +---------+ 1 row in set (0.01 sec)
-
等価クエリと範囲クエリ
-
DateTimeV2列に対する範囲クエリのパフォーマンスを比較します。-
転置インデックスがない場合、
timestampが2007-08-23 04:17:00より大きい行数をカウントするクエリは 0.03s かかります。SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00'; +---------+ | count() | +---------+ | 999081 | +---------+ 1 row in set (0.03 sec) -
timestamp列に転置インデックスを追加します。CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED; Query OK, 0 rows affected (0.03 sec) -
インデックス作成の進行状況を確認します。FinishTime と CreateTime の差から、timestamp 列の 100 万行に対する転置インデックスの作成にかかった時間はわずか 1 秒であることがわかります。
SHOW ALTER TABLE COLUMN; +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ | JobId | TableName | CreateTime | FinishTime | IndexName | IndexId | OriginIndexId | SchemaVersion | TransactionId | State | Msg | Progress | Timeout | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031 | 10008 | 1:1994690496 | 3 | FINISHED | | NULL | 2592000 | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ 1 row in set (0.00 sec) -
転置インデックスを作成した後、timestamp 列が
2007-08-23 04:17:00より大きいデータをカウントする同じクエリは 0.01 秒で実行されます。これは、転置インデックスがない場合と比較して 2 秒の高速化に相当します。SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00'; +---------+ | count() | +---------+ | 999081 | +---------+ 1 行 (0.01 秒)
-
-
数値列に対する等価クエリのパフォーマンスを比較します。
-
転置インデックスがない場合、parent 列が 11189 に等しい行をカウントするクエリは 0.01 秒かかります。
SELECT count() FROM hackernews_1m WHERE parent = 11189; +---------+ | count() | +---------+ | 2 | +---------+ 1 row in set (0.01 sec) -
数値型の
parent列にトークナイザーなしで転置インデックスを作成します。-- 数値型の場合、INVERTED を使用する際にトークナイザーを指定する必要はありません。 -- ALTER TABLE ... ADD INDEX は、インデックスを作成するための代替構文です。 ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED; Query OK, 0 rows affected (0.01 sec) -
インデックス作成の進行状況を確認します。
SHOW ALTER TABLE COLUMN; +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ | JobId | TableName | CreateTime | FinishTime | IndexName | IndexId | OriginIndexId | SchemaVersion | TransactionId | State | Msg | Progress | Timeout | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031 | 10008 | 1:1994690496 | 3 | FINISHED | | NULL | 2592000 | | 10053 | hackernews_1m | 2023-02-10 19:49:32.893 | 2023-02-10 19:49:33.982 | hackernews_1m | 10054 | 10008 | 1:378856428 | 4 | FINISHED | | NULL | 2592000 | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ -
同じクエリを再度実行します。クエリ時間は 0.01 秒のままで、このデータセットでは大きな変化は見られません。
SELECT count() FROM hackernews_1m WHERE parent = 11189; +---------+ | count() | +---------+ | 2 | +---------+ 1 row in set (0.01 sec)
-
-
文字列列に対する等価クエリのパフォーマンスを比較します。
-
転置インデックスがない場合、author 列が 'faster' に等しい行をカウントするクエリは 0.03 秒かかります。
SELECT count() FROM hackernews_1m WHERE author = 'faster'; +---------+ | count() | +---------+ | 20 | +---------+ 1 row in set (0.03 sec) -
author列にトークナイザーなしで転置インデックスを作成します。-- この例では、USING INVERTED のみが指定されています。author 列の値はトークン化されず、各値は単一のタームとして扱われます。 ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED; Query OK, 0 rows affected (0.01 sec) -
インデックス作成の進行状況を確認します。
-- 100 万行のデータを持つ author 列にインデックスを段階的に作成するのに、わずか 1.5 秒しかかかりません。 SHOW ALTER TABLE COLUMN; +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ | JobId | TableName | CreateTime | FinishTime | IndexName | IndexId | OriginIndexId | SchemaVersion | TransactionId | State | Msg | Progress | Timeout | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031 | 10008 | 1:1994690496 | 3 | FINISHED | | NULL | 2592000 | | 10053 | hackernews_1m | 2023-02-10 19:49:32.893 | 2023-02-10 19:49:33.982 | hackernews_1m | 10054 | 10008 | 1:378856428 | 4 | FINISHED | | NULL | 2592000 | | 10076 | hackernews_1m | 2023-02-10 19:54:20.046 | 2023-02-10 19:54:21.521 | hackernews_1m | 10077 | 10008 | 1:1335127701 | 5 | FINISHED | | NULL | 2592000 | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ -
インデックスの作成後、クエリはわずか 0.01 秒で完了し、3 倍速くなります。
-- インデックスの作成後、文字列の等価マッチングも大幅に高速化されます。 SELECT count() FROM hackernews_1m WHERE author = 'faster'; +---------+ | count() | +---------+ | 20 | +---------+ 1 row in set (0.01 sec)
-
TOKENIZE 関数
TOKENIZE 関数は、テキスト文字列を一連のタームに分割します。トークン化は、転置インデックスを構築して使用するためのコアコンポーネントです。トークン化の品質は、インデックスのパフォーマンスに直接影響します。
文字列がどのようにトークン化されるかを確認するには、TOKENIZE 関数を使用して結果を表示します。TOKENIZE 関数には、parser と parser_mode という 2 つの主要なパラメーターがあります。次の表で、これらのパラメーターについて説明します。
|
パラメーター |
説明 |
|
|
使用するトークナイザーを指定します。このパラメーターを省略すると、関数はトークン化を実行しません。
|
|
|
トークン化モードを指定します。これにより、トークン化の粒度が決まります。 すべてのトークナイザーは、デフォルトで粗粒度モードを使用します。このモードは、テキストをより長い単語に分割する傾向があります。たとえば、文字列 中国語のトークナイザーに |
例:
-- 英語のトークン化結果。
SELECT TOKENIZE('I love CHINA','"parser"="english"');
+------------------------------------------------+
| tokenize('I love CHINA', '"parser"="english"') |
+------------------------------------------------+
| ["i", "love", "china"] |
+------------------------------------------------+
1 row in set (0.02 sec)
-- 中国語トークナイザー (細粒度モード) のトークン化結果。
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="fine_grained"') |
+-------------------------------------------------------------------------------------+
| ["武汉", "武汉市", "市长", "长江", "长江大桥", "大桥"] |
+-------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
-- 中国語トークナイザー (粗粒度モード) のトークン化結果。
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="coarse_grained"');
+----------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="coarse_grained"') |
+----------------------------------------------------------------------------------------+
| ["武汉市", "长江大桥"] |
+----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
-- 多言語混在のトークン化結果。
SELECT TOKENIZE('I love CHINA 我爱我的祖国','"parser"="unicode"');
+-------------------------------------------------------------------+
| tokenize('I love CHINA 我爱我的祖国', '"parser"="unicode"') |
+-------------------------------------------------------------------+
| ["i", "love", "china", "我", "爱", "我", "的", "祖", "国"] |
+-------------------------------------------------------------------+
1 row in set (0.02 sec)