O índice invertido é uma técnica comum de indexação em recuperação de informações. Ele funciona tokenizando texto em termos para construir um índice, permitindo recuperar rapidamente documentos que contêm esses termos.ApsaraDB for SelectDB oferece suporte a índices invertidos. Use esse recurso para realizar buscas de texto completo em tipos de dados de texto e executar consultas de igualdade e intervalo em tipos numéricos e de data, filtrando grandes conjuntos de dados com agilidade. Este tópico descreve o recurso de índice invertido no ApsaraDB for SelectDB, incluindo como criá-lo e utilizá-lo.
Como funciona
No Alibaba Cloud SelectDB, o índice invertido trata cada linha da tabela como um documento e cada coluna como um campo. Isso permite localizar rapidamente as linhas que contêm uma palavra-chave específica, melhorando o desempenho de consultas que utilizam a cláusula WHERE.
Diferentemente de um índice comum, o índice invertido é armazenado em um arquivo invertido separado. Esse arquivo é mapeado logicamente para o arquivo de segmento, mas não se integra a ele. Essa abordagem evita a reescrita do arquivo de segmento durante atualizações e exclusões de índice, reduzindo significativamente a sobrecarga de processamento.
Cenários
Acelera a busca de texto completo em tipos de dados string.
Acelera a filtragem com
=, !=, >, >=, <, <=para tipos string, numéricos e datetime.
Benefícios
-
Suporte abrangente a operadores lógicos.
Adição de suporte para pushdown de índice com lógica
OR and NOT.Compatibilidade com qualquer combinação de múltiplas condições usando
AND, OR, and NOT.
-
Gerenciamento de índice flexível e rápido.
Crie um índice invertido durante a criação da tabela.
Adicione um índice invertido a uma tabela existente.
Exclua um índice invertido de uma tabela.
Limitações
Os tipos de dados de ponto flutuante
FLOATeDOUBLEnão oferecem suporte a índice invertido devido a questões de precisão. Em vez disso, utilize o tipo de dados de ponto fixoDECIMAL, que possui suporte a índice invertido.Alguns tipos de dados complexos não suportam índice invertido, incluindo
MAP,STRUCT,JSON,HLL,BITMAP,QUANTILE_STATEeAGG_STATE. Para usar um índice invertido com dadosJSON, converta a coluna para o tipo de dadosVARIANT.É possível criar um índice invertido em um campo de tipo numérico, mas não é permitido especificar um
parser, comoenglish,chineseouunicode.O modelo
DUPLICATEe o modeloUNIQUEcom Merge on Write ativado suportam índice invertido em qualquer coluna. Por outro lado, o modeloAGGREGATEe o modeloUNIQUEcom Merge on Write desativado suportam índice invertido apenas em colunas Key. Como esses modelos precisam ler e mesclar todos os dados, o sistema não consegue utilizar o índice para pré-filtragem.
Criar um índice
Crie um índice invertido durante a criação da tabela ou em uma coluna de uma tabela existente.
Criar índice na criação da tabela
Esta é uma operação síncrona. A criação do índice é concluída quando a tabela é criada com sucesso.
Os índices invertidos apresentam as seguintes limitações nos diferentes modelos de dados:
No modelo de chave agregada, só é possível criar um índice invertido em colunas de chave.
No modelo de chave única, o recurso Merge on Write deve estar ativado. Após a ativação, crie um índice invertido em qualquer coluna.
No modelo de chave duplicada, crie um índice invertido em qualquer coluna.
Sintaxe
CREATE TABLE [IF NOT EXISTS] [db_name.]<table_name>
(
<column_definition_list>,
[<index_definition_list>]
)
table_properties;
Parâmetros
Parâmetros de criação de tabela
|
Parameter |
Required |
Description |
|
db_name |
No |
Nome do banco de dados que conterá a tabela. |
|
table_name |
Yes |
Nome da tabela a ser criada. |
|
column_definition_list |
Yes |
Lista de definições de colunas. Para mais informações, consulte CREATE-TABLE. |
|
table_properties |
Yes |
Propriedades da tabela, como modelo de dados, particionamento e bucketing. Para mais informações, consulte modelo de dados. |
|
index_definition_list |
No |
Lista de definições de índices. |
index_definition_list
Defina um ou mais índices ao criar uma tabela. Utilize o seguinte formato: index_definition[, index_definition][, index_definition]....
index_definition
INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")] [COMMENT '<comment>']
Parâmetros
Parâmetros obrigatórios
|
Parameter |
Description |
|
index_name |
Nome do índice. |
|
column_name |
Nome da coluna a ser indexada. |
|
index_type |
Tipo do índice. Defina como |
Parâmetros opcionais
Properties
A cláusula PROPERTIES especifica as opções de tokenização para o índice. Ela consiste em um ou mais pares chave-valor separados por vírgulas no formato "<key>" = "<value>". Caso tenha dúvidas sobre como um determinado texto será tokenizado, utilize a função TOKENIZE para visualizar a saída. Para mais informações, consulte Funções de tokenização.
|
Key |
Value |
|
parser |
Especifica o tokenizador. Se esta propriedade for omitida, nenhuma tokenização ocorrerá. A propriedade
|
|
parser_mode |
Especifica o modo de tokenização de palavras, que determina a granularidade da tokenização. Todos os tokenizadores usam o modo coarse_grained por padrão. Esse modo tende a segmentar o texto em palavras mais longas. Por exemplo, Quando Para saber mais sobre o funcionamento da tokenização, consulte Funções de tokenização. |
|
support_phrase |
Especifica se o índice suporta consultas de frase
|
|
char_filter |
Pré-processa strings antes da tokenização. Atualmente,
|
|
ignore_above |
Especifica um limite de comprimento para valores de string não tokenizados (quando nenhum
|
|
lower_case |
Especifica se os termos tokenizados devem ser convertidos para minúsculas para correspondência sem distinção entre maiúsculas e minúsculas.
|
|
stopwords |
Especifica uma lista de stopwords, o que afeta o comportamento do tokenizador.
|
|
dict_compression |
Especifica se a compressão de dicionário Zstandard (ZSTD) deve ser ativada para o dicionário do índice invertido.
Nota
Este parâmetro é suportado apenas nas versões 4.1.0 e posteriores. |
Comment
|
Parameter |
Description |
|
comment |
Descrição do índice. |
Exemplo: Criar uma tabela com um índice
-- Create a table and an inverted index named idx_comment on the comment column.
-- USING INVERTED sets the index type to inverted index.
-- PROPERTIES("parser" = "english") sets the tokenizer to "english". Other supported tokenizers include "chinese" for Chinese text and "unicode" for mixed-language text. If the "parser" property is omitted, no tokenization occurs.
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;
Adicionar um índice
Esta é uma operação assíncrona. Verifique o progresso da criação do índice usando SHOW ALTER TABLE COLUMN;.
Sintaxe
ALTER TABLE <table_name> ADD INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")];
Parâmetros
Os parâmetros são os mesmos utilizados na criação da tabela.
Exemplos
Adicione um índice sem tokenização.
ALTER TABLE user_tb ADD INDEX index_userId(user_id) USING INVERTED ;
Adicione um índice que utiliza english para tokenização.
ALTER TABLE user_tb ADD INDEX index_city(city) USING INVERTED PROPERTIES("parser" = "english");
Visualizar índices invertidos
Visualizar progresso de alteração do índice
A modificação de um índice invertido usando os comandos ALTER e DROP é um processo assíncrono. Para acompanhar o progresso, execute a seguinte instrução.
SHOW ALTER TABLE COLUMN;
Visualizar todos os índices invertidos da tabela
Sintaxe
SHOW INDEXES FROM <table_name>;
Exemplo
SHOW INDEXES FROM user_tb;
Excluir um índice
A exclusão de um índice é um processo assíncrono. Para verificar o progresso, consulte Consultar informações sobre índices invertidos.
Excluir um índice pode reduzir o desempenho das consultas. Proceda com cautela.
Sintaxe
-- Syntax 1
DROP INDEX <index_name> ON <table_name>;
-- Syntax 2
ALTER TABLE <table_name> DROP INDEX <index_name>;
Exemplo
DROP INDEX index_userId ON user_tb;
ALTER TABLE user_tb DROP INDEX index_city;
Índice invertido
Busca de texto completo
Sintaxe
SELECT * FROM <table_name> WHERE <column_name> <conditional_logic> '<keywords>';
Parâmetros
|
Parameter |
Required |
Description |
|
table_name |
Yes |
Nome da tabela. |
|
column_name |
Yes |
Nome da coluna. |
|
conditional_logic |
Yes |
Combinação de operadores de busca e operadores lógicos. Operadores lógicos: Operadores de busca:
|
|
keywords |
Yes |
Palavras-chave de busca. Separe múltiplas palavras-chave com espaços. Exemplo: |
Exemplos
-- Retrieve rows where logmsg contains keyword1.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';
-- Retrieve rows where logmsg contains keyword1 or keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';
-- Retrieve rows where logmsg contains both keyword1 and keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';
-- Retrieve rows where logmsg contains the exact phrase "keyword1 keyword2".
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';
Consultas de igualdade e intervalo para numéricos e datas
A sintaxe de consulta segue o padrão SQL.
Exemplo
-- Equality, range, IN, and NOT IN queries
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');
Comparação de desempenho de consultas
Este tópico utiliza um conjunto de dados hackernews com 1 milhão de linhas para comparar o desempenho de consultas com e sem índice invertido.
Pré-requisitos
Passo 1: Crie uma tabela.
-
Crie um banco de dados.
CREATE DATABASE test_inverted_index; -
Mude para o banco de dados criado.
USE test_inverted_index; -
Crie a tabela de destino.
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; -- Creates a table and an inverted index named idx_comment on the comment column. -- USING INVERTED specifies that the index type is an inverted index. -- PROPERTIES("parser" = "english") specifies that the English tokenizer is used. You can also specify "chinese" for Chinese text or "unicode" for mixed-language text. If you do not specify the "parser" parameter, no tokenization is performed.
Passo 2: Importe os dados
-
Baixe o arquivo de dados.
wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz -
Importe os dados usando Stream Load.
Na página de detalhes da instância do ApsaraDB for SelectDB, visualize o host do endpoint e o número da porta de uma instância do ApsaraDB for SelectDB. Para mais informações sobre Stream Load, consulte 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 } -
Execute uma consulta
count()para verificar a importação dos dados.SELECT count() FROM hackernews_1m; +---------+ | count() | +---------+ | 1000000 | +---------+ 1 row in set (0.02 sec)
Comparação de desempenho
Os resultados de contagem podem diferir entre consultas que usam um índice invertido com tokenizador e aquelas que não usam. Isso ocorre porque o índice invertido tokeniza os dados da coluna e normaliza os termos (por exemplo, convertendo-os para minúsculas), o que pode fazer com que as consultas que usam o índice correspondam a mais linhas.
A diferença de desempenho em alguns exemplos pode não ser significativa porque o conjunto de dados é pequeno. Quanto maior o conjunto de dados, maior a melhoria de desempenho.
Busca de texto completo
-
Conte as linhas onde a coluna
commentcontémOLAP.-
A contagem do número de linhas na coluna
commentque contêmOLAPusando o operadorLIKEleva 0,18s.SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%'; +---------+ | count() | +---------+ | 34 | +---------+ 1 row in set (0.18 sec) -
A busca de texto completo
MATCH_ANYbaseada em índice invertido conta o número de linhas na coluna comment que contêmOLAPem 0,02s. Isso é 9 vezes mais rápido do que usar o operadorLIKE.SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP'; +---------+ | count() | +---------+ | 35 | +---------+ 1 row in set (0.02 sec)
-
-
Conte as linhas onde a coluna
commentcontémOLTP.-
Esta operação conta o número de linhas na coluna
commentque contêmOLTPusando o operadorLIKEe leva 0,07s.SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%'; +---------+ | count() | +---------+ | 48 | +---------+ 1 row in set (0.07 sec) -
A busca de texto completo
MATCH_ANYbaseada em índice invertido conta o número de linhas na colunacommentque contêmOLTPem 0,01s. Isso é 7 vezes mais rápido do que usar o operadorLIKE.SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP'; +---------+ | count() | +---------+ | 51 | +---------+ 1 row in set (0.01 sec)
-
-
Conte as linhas onde a coluna
commentcontém tantoOLAPquantoOLTP.-
Usando
LIKE, a consulta leva 0,13s.SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%'; +---------+ | count() | +---------+ | 14 | +---------+ 1 row in set (0.13 sec) -
Usando busca de texto completo com
MATCH_ALL, a consulta leva 0,01s, tornando-a 13 vezes mais rápida do que usarLIKE.SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP'; +---------+ | count() | +---------+ | 15 | +---------+ 1 row in set (0.01 sec)
-
-
Conte as linhas onde a coluna
commentcontémOLAPouOLTP.-
Usando
LIKE, a consulta leva 0,12s.SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%'; +---------+ | count() | +---------+ | 68 | +---------+ 1 row in set (0.12 sec) -
Usando busca de texto completo com
MATCH_ANY, a consulta leva 0,01s, tornando-a 12 vezes mais rápida do que usarLIKE.SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP OLTP'; +---------+ | count() | +---------+ | 71 | +---------+ 1 row in set (0.01 sec)
-
Consultas de igualdade e intervalo
-
Compare o desempenho de uma consulta de intervalo em uma coluna
DateTimeV2.-
Sem um índice invertido, uma consulta para contar linhas onde
timestampé maior que2007-08-23 04:17:00leva 0,03s.SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00'; +---------+ | count() | +---------+ | 999081 | +---------+ 1 row in set (0.03 sec) -
Adicione um índice invertido à coluna
timestamp.CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED; Query OK, 0 rows affected (0.03 sec) -
Verifique o progresso da criação do índice. A diferença entre FinishTime e CreateTime mostra que a criação do índice invertido para 1 milhão de linhas na coluna timestamp levou apenas 1 segundo.
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) -
Após a criação do índice invertido, executar a mesma consulta para contar dados onde a coluna timestamp é maior que
2007-08-23 04:17:00leva 0,01 segundos. Isso representa uma melhoria de 2 segundos em comparação com a velocidade da consulta sem índice invertido.SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00'; +---------+ | count() | +---------+ | 999081 | +---------+ 1 row in set (0.01 sec)
-
-
Compare o desempenho de uma consulta de igualdade em uma coluna numérica.
-
Sem um índice invertido, uma consulta para contar linhas onde a coluna parent é igual a 11189 leva 0,01s.
SELECT count() FROM hackernews_1m WHERE parent = 11189; +---------+ | count() | +---------+ | 2 | +---------+ 1 row in set (0.01 sec) -
Crie um índice invertido na coluna numérica
parentsem tokenizador.-- For numeric types, you do not need to specify a tokenizer when using INVERTED. -- ALTER TABLE ... ADD INDEX is an alternative syntax for creating an index. ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED; Query OK, 0 rows affected (0.01 sec) -
Verifique o progresso da criação do índice.
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 | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ -
Execute a mesma consulta novamente. O tempo de consulta permanece 0,01s, não mostrando alteração significativa para este conjunto de dados.
SELECT count() FROM hackernews_1m WHERE parent = 11189; +---------+ | count() | +---------+ | 2 | +---------+ 1 row in set (0.01 sec)
-
-
Compare o desempenho de uma consulta de igualdade em uma coluna string.
-
Sem um índice invertido, uma consulta para contar linhas onde a coluna author é igual a 'faster' leva 0,03s.
SELECT count() FROM hackernews_1m WHERE author = 'faster'; +---------+ | count() | +---------+ | 20 | +---------+ 1 row in set (0.03 sec) -
Crie um índice invertido na coluna
authorsem tokenizador.-- In this example, only USING INVERTED is specified. The values in the author column are not tokenized, and each value is treated as a single term. ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED; Query OK, 0 rows affected (0.01 sec) -
Verifique o progresso da criação do índice.
-- It takes only 1.5s to incrementally create an index on the author column with 1 million rows of data. 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 | +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+ -
Após criar o índice, a consulta leva apenas 0,01s, tornando-a 3 vezes mais rápida.
-- After the index is created, string equality matching is also significantly accelerated. SELECT count() FROM hackernews_1m WHERE author = 'faster'; +---------+ | count() | +---------+ | 20 | +---------+ 1 row in set (0.01 sec)
-
Função Tokenize
A função TOKENIZE divide uma string de texto em uma sequência de termos. A tokenização é um componente central para construir e usar um índice invertido. A qualidade da tokenização impacta diretamente o desempenho do índice.
Para ver como uma string de texto é tokenizada, use a função TOKENIZE para visualizar o resultado. A função TOKENIZE possui dois parâmetros principais: parser e parser_mode. A tabela a seguir descreve esses parâmetros.
|
Parameter |
Description |
|
|
Especifica o tokenizador a ser usado. Se este parâmetro for omitido, a função não realiza tokenização.
|
|
|
Especifica o modo de tokenização, que determina a granularidade da tokenização. Todos os tokenizadores usam o modo coarse_grained por padrão. Esse modo tende a segmentar o texto em palavras mais longas. Por exemplo, a string Quando |
Exemplos:
-- English tokenization result.
SELECT TOKENIZE('I love CHINA','"parser"="english"');
+------------------------------------------------+
| tokenize('I love CHINA', '"parser"="english"') |
+------------------------------------------------+
| ["i", "love", "china"] |
+------------------------------------------------+
1 row in set (0.02 sec)
-- Fine-grained tokenization result from the Chinese tokenizer.
SELECT TOKENIZE('武汉长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-----------------------------------------------------------------------------------+
| tokenize('武汉长江大桥', '"parser"="chinese","parser_mode"="fine_grained"') |
+-----------------------------------------------------------------------------------+
| ["武汉", "武汉长江大桥", "长江", "长江大桥", "大桥"] |
+-----------------------------------------------------------------------------------+
1 row in set (0.02 sec)
-- Coarse-grained tokenization result from the Chinese tokenizer.
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="coarse_grained"');
+----------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="coarse_grained"') |
+----------------------------------------------------------------------------------------+
| ["武汉市", "长江大桥"] |
+----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
-- Mixed-language tokenization result.
SELECT TOKENIZE('I love CHINA 我爱我的祖国','"parser"="unicode"');
+-------------------------------------------------------------------+
| tokenize('I love CHINA 我爱我的祖国', '"parser"="unicode"') |
+-------------------------------------------------------------------+
| ["i", "love", "china", "我", "爱", "我", "的", "祖", "国"] |
+-------------------------------------------------------------------+
1 row in set (0.02 sec)