这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

词干分析器和分词器

Vertica 提供默认词干分析器和分词器。您也可以创建自己的自定义词干分析器和分词器。以下主题介绍了默认词干分析器和分词器,以及在 Vertica 中创建自定义词干分析器和分词器的要求。

1 - Vertica 词干分析器

Vertica 词干分析器采用 Porter 词干抽取算法来查找从同一基词/根词派生的词语。例如,在文本索引中搜索关键字 database 时,您可能还希望获得包含 databases 一词的结果。

为了实现这种类型的匹配,当使用任何 v_txtindex 词干分析器时,Vertica 都会以已抽取词干的形式存储词语。

Vertica Analytics Platform 提供了以下词干分析器:

示例

以下示例显示了创建文本索引时如何使用词干分析器。

使用 StemmerCaseInsensitive 词干分析器创建文本索引:

=> CREATE TEXT INDEX idx_100 ON top_100 (id, feedback) STEMMER v_txtindex.StemmerCaseInsensitive(long varchar)
                                                              TOKENIZER v_txtindex.StringTokenizer(long varchar);

使用 StemmerCaseSensitive 词干分析器创建文本索引:

=> CREATE TEXT INDEX idx_unstruc ON unstruc_data (__identity__, __raw__) STEMMER v_txtindex.StemmerCaseSensitive(long varchar)
                                                                                  TOKENIZER public.FlexTokenizer(long varbinary);

在不使用词干分析器的情况下创建文本索引:

=> CREATE TEXT INDEX idx_logs FROM sys_logs ON (id, message) STEMMER NONE TOKENIZER v_txtindex.StringTokenizer(long varchar);

2 - Vertica 分词器

分词器执行以下操作:

  • 接收字符流。

  • 将该流分解为通常对应于各个单词的各个标记。

  • 返回标记流。

2.1 - 预配置的分词器

Vertica Analytics Platform 提供以下预配置的分词器:

Vertica 还提供了以下未预配置的分词器:

示例

以下示例显示了在创建文本索引时如何使用预配置的分词器。

使用 StringTokenizer 从 top_100 创建索引:

=> CREATE TEXT INDEX idx_100 FROM top_100 on (id, feedback)
                TOKENIZER v_txtindex.StringTokenizer(long varchar)
                 STEMMER v_txtindex.StemmerCaseInsensitive(long varchar);

使用 FlexTokenizer 从非结构化数据创建索引:

=> CREATE TEXT INDEX idx_unstruc FROM unstruc_data on (__identity__, __raw__)
                                 TOKENIZER public.FlexTokenizer(long varbinary)
                                    STEMMER v_txtindex.StemmerCaseSensitive(long varchar);

使用 StringTokenizerDelim 在指定的分隔符处拆分字符串:

=> CREATE TABLE string_table (word VARCHAR(100), delim VARCHAR);
CREATE TABLE
=> COPY string_table FROM STDIN DELIMITER ',';
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>>
>> SingleWord,dd
>> Break On Spaces,' '
>> Break:On:Colons,:
>> \.
=> SELECT * FROM string_table;
            word | delim
-----------------+-------
      SingleWord | dd
 Break On Spaces |
 Break:On:Colons | :
(3 rows)

=> SELECT v_txtindex.StringTokenizerDelim(word,delim) OVER () FROM string_table;
      words
-----------------
 Break
 On
 Colons
 SingleWor
 Break
 On
 Spaces
(7 rows)

=> SELECT v_txtindex.StringTokenizerDelim(word,delim) OVER (PARTITION BY word), word as input FROM string_table;
           words | input
-----------------+-----------------
           Break | Break:On:Colons
              On | Break:On:Colons
          Colons | Break:On:Colons
       SingleWor | SingleWord
           Break | Break On Spaces
              On | Break On Spaces
          Spaces | Break On Spaces
(7 rows)

2.2 - 高级日志分词器

返回可包含二级分隔符的令牌。在令牌由空格或多种标点分隔的情况下可以使用此分词器。在通过添加二级分隔符定义分隔符方面,高级日志分词器能比基本日志分词器提供更大的粒度。这一方法通常适用于分析日志文件。

参数

示例

以下示例显示了如何在没有词干分析器的情况下使用高级日志分词器从表 foo 创建文本索引。

=> CREATE TABLE foo (id INT PRIMARY KEY NOT NULL,text VARCHAR(250));
=> COPY foo FROM STDIN;
End with a backslash and a period on a line by itself.
>> 1|2014-05-10 00:00:05.700433 %ASA-6-302013: Built outbound TCP connection 9986454 for outside:101.123.123.111/443 (101.123.123.111/443)
>> \.
=> CREATE PROJECTION foo_projection AS SELECT * FROM foo ORDER BY id
                                    SEGMENTED BY HASH(id) ALL NODES KSAFE;
=> CREATE TEXT INDEX indexfoo_AdvancedLogTokenizer ON foo (id, text)
                  TOKENIZER v_txtindex.AdvancedLogTokenizer(LONG VARCHAR) STEMMER NONE;
=> SELECT * FROM indexfoo_AdvancedLogTokenizer;
            token            | doc_id
-----------------------------+--------
 %ASA-6-302013:              |      1
 00                          |      1
 00:00:05.700433             |      1
 05                          |      1
 10                          |      1
 101                         |      1
 101.123.123.111/443         |      1
 111                         |      1
 123                         |      1
 2014                        |      1
 2014-05-10                  |      1
 302013                      |      1
 443                         |      1
 700433                      |      1
 9986454                     |      1
 ASA                         |      1
 Built                       |      1
 TCP                         |      1
 connection                  |      1
 for                         |      1
 outbound                    |      1
 outside                     |      1
 outside:101.123.123.111/443 |      1
(23 rows)

2.3 - 基本日志分词器

返回不包含指定二级分隔符的令牌。在令牌由空格或多种标点分隔的情况下可以使用此分词器。这一方法通常适用于分析日志文件。

参数

示例

以下示例显示了如何在没有词干分析器的情况下使用基本日志分词器从表 foo 创建文本索引。

=> CREATE TABLE foo (id INT PRIMARY KEY NOT NULL,text VARCHAR(250));
=> COPY foo FROM STDIN;
End with a backslash and a period on a line by itself.
>> 1|2014-05-10 00:00:05.700433 %ASA-6-302013: Built outbound TCP connection 9986454 for outside:101.123.123.111/443 (101.123.123.111/443)
>> \.
=> CREATE PROJECTION foo_projection AS SELECT * FROM foo ORDER BY id
                                     SEGMENTED BY HASH(id) ALL NODES KSAFE;
=> CREATE TEXT INDEX indexfoo_BasicLogTokenizer ON foo (id, text)
                 TOKENIZER v_txtindex.BasicLogTokenizer(LONG VARCHAR) STEMMER NONE;
=> SELECT * FROM indexfoo_BasicLogTokenizer;
            token            | doc_id
-----------------------------+--------
 %ASA-6-302013:              |      1
 00:00:05.700433             |      1
 101.123.123.111/443         |      1
 2014-05-10                  |      1
 9986454                     |      1
 Built                       |      1
 TCP                         |      1
 connection                  |      1
 for                         |      1
 outbound                    |      1
 outside:101.123.123.111/443 |      1
(11 rows)

2.4 - 空格日志分词器

仅返回由空格所包围的令牌。如果您只希望用空格字符来分隔源文档中的令牌,可以使用此分词器。使用这种方法时,您仍然能够设置非索引字和令牌长度限制。

参数

示例

以下示例显示了如何在没有词干分析器的情况下使用空格日志分词器从表 foo 创建文本索引。

=> CREATE TABLE foo (id INT PRIMARY KEY NOT NULL,text VARCHAR(250));
=> COPY foo FROM STDIN;
End with a backslash and a period on a line by itself.
>> 1|2014-05-10 00:00:05.700433 %ASA-6-302013: Built outbound TCP connection 998 6454 for outside:101.123.123.111/443 (101.123.123.111/443)
>> \.
=> CREATE PROJECTION foo_projection AS SELECT * FROM foo ORDER BY id
                                     SEGMENTED BY HASH(id) ALL NODES KSAFE;
=> CREATE TEXT INDEX indexfoo_WhitespaceLogTokenizer ON foo (id, text)
                TOKENIZER v_txtindex.WhitespaceLogTokenizer(LONG VARCHAR) STEMMER NONE;
=> SELECT * FROM indexfoo_WhitespaceLogTokenizer;
            token            | doc_id
-----------------------------+--------
 %ASA-6-302013:              |      1
 (101.123.123.111/443)       |      1
 00:00:05.700433             |      1
 2014-05-10                  |      1
 6454                        |      1
 998                         |      1
 Built                       |      1
 TCP                         |      1
 connection                  |      1
 for                         |      1
 outbound                    |      1
 outside:101.123.123.111/443 |      1
(12 rows)

2.5 - ICU 分词器

支持多种语言。可以使用此分词器识别非英语语言中的单词边界,包括未用空格分隔的亚洲语言。

ICU 分词器未预先配置。可以通过首先创建用户定义的转换函数 (UDTF) 来配置分词器。然后设置参数 locale 来标识分词器的语言。

参数

示例

以下示例步骤显示了如何将 ICU 分词器配置为简体中文,然后从包含中文字符的表 foo 中创建文本索引。

有关如何配置分词器的详细信息,请参阅配置分词器

  1. 使用 UDTF 创建分词器。将示例分词器命名为 ICUChineseTokenizer。

    VMart=> CREATE OR REPLACE TRANSFORM FUNCTION v_txtindex.ICUChineseTokenizer AS LANGUAGE 'C++' NAME 'ICUTokenizerFactory' LIBRARY v_txtindex.logSearchLib NOT FENCED;
    CREATE TRANSFORM FUNCTION
    
  2. 获取分词器的过程 ID。

    VMart=> SELECT proc_oid from vs_procedures where procedure_name = 'ICUChineseTokenizer';
    
         proc_oid
    -------------------
     45035996280452894
    (1 row)
    
  3. 将参数 locale 设置为简体中文。使用过程 ID 标识分词器。

    VMart=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('locale','zh_CN' using parameters proc_oid='45035996280452894');
     SET_TOKENIZER_PARAMETER
    -------------------------
     t
    (1 row)
    
  4. 锁定分词器。

    VMart=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('used','true' using parameters proc_oid='45035996273762696');
     SET_TOKENIZER_PARAMETER
    -------------------------
     t
    (1 row)
    
  5. 创建示例表 foo,其中包含要编制索引的简体中文文本。

    VMart=> CREATE TABLE foo(doc_id integer primary key not null,text varchar(250));
    CREATE TABLE
    
    
    VMart=> INSERT INTO foo values(1, u&'\4E2D\534E\4EBA\6C11\5171\548C\56FD');
     OUTPUT
    --------
          1
    
  6. 对表 foo 创建索引 index_example。该示例在没有词干分析器的情况下创建索引;Vertica 词干分析器仅适用于英语文本。对非英语文本使用英语词干分析器可能会导致分词不正确。

    VMart=> CREATE TEXT INDEX index_example ON foo (doc_id, text) TOKENIZER v_txtindex.ICUChineseTokenizer(long varchar) stemmer none;
    CREATE INDEX
    
  7. 查看新索引。

    VMart=> SELECT * FROM index_example ORDER BY token,doc_id;
     token  | doc_id
    --------+--------
     中华    |      1
     人民   |      1
     共和国 |      1
    (3 rows)
    

3 - 配置分词器

可以通过使用 v_txtindex.AdvTxtSearchLib 库中的两个基本用户定义的转换函数 (UDTF) 之一创建 UDTF,来配置分词器。库中包含两个基本分词器:一个用于 Log Words,一个用于 Ngrams。可以配置每个具有或不具有位置相关性的基本函数。

3.1 - 分词器基本配置

可以在多个不同的分词器基本配置中进行选择:

创建没有位置相关性的 logWord 分词器:

=> CREATE TRANSFORM FUNCTION v_txtindex.fooTokenizer AS LANGUAGE 'C++' NAME 'logWordITokenizerFactory' LIBRARY v_txtindex.logSearchLib NOT FENCED;

3.2 - RetrieveTokenizerproc_oid

创建分词器之后,Vertica 将名称和 proc_oid 写入系统表 vs_procedures 中。必须检索分词器的 proc_oid 以执行其他配置。

输入以下查询,替换您自己的分词器名称:

=> SELECT proc_oid FROM vs_procedures WHERE procedure_name = 'fooTokenizer';

3.3 - 设置分词器参数

使用分词器的 proc_oid 可以配置分词器。有关获取分词器 proc_oid 的详细信息,请参阅配置分词器。以下示例显示了如何配置各个分词器参数:

配置非索引字:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('stopwordscaseinsensitive','for,the' USING PARAMETERS proc_oid='45035996274128376');

配置主要分隔符:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('majorseparators', E'{}()&[]' USING PARAMETERS proc_oid='45035996274128376');

配置二级分隔符:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('minorseparators', '-,$' USING PARAMETERS proc_oid='45035996274128376');

配置最小长度:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('minlength', '1' USING PARAMETERS proc_oid='45035996274128376');

配置最大长度:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('maxlength', '140' USING PARAMETERS proc_oid='45035996274128376');

配置 ngramssize:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('ngramssize', '2' USING PARAMETERS proc_oid='45035996274128376');

锁定分词器参数

配置完分词器时,请将参数 used 设置为 True。更改此设置后,将不能再更改分词器的参数。此时即可使用分词器来创建文本索引。

配置 used 参数:

=> SELECT v_txtindex.SET_TOKENIZER_PARAMETER('used', 'True' USING PARAMETERS proc_oid='45035996274128376');

另请参阅

SET_TOKENIZER_PARAMETER

3.4 - 查看分词器参数

创建自定义分词器之后,您可以通过以下两种任一方式查看分词器的参数设置:

查看单个分词器参数设置

如果您需要查看分词器的单个参数设置,可以使用 GET_TOKENIZER_PARAMETER 查看特定的分词器参数设置:

=> SELECT v_txtindex.GET_TOKENIZER_PARAMETER('majorseparators' USING PARAMETERS proc_oid='45035996274126984');
 getTokenizerParameter
-----------------------
 {}()&[]
(1 row)

有关详细信息,请参阅GET_TOKENIZER_PARAMETER

查看所有分词器参数设置

如果您需要查看分词器的所有参数,可以使用 READ_CONFIG_FILE 查看分词器的所有参数设置:

=> SELECT v_txtindex.READ_CONFIG_FILE( USING PARAMETERS proc_oid='45035996274126984') OVER();
               config_key | config_value
--------------------------+---------------
          majorseparators | {}()&[]
                maxlength | 140
                minlength | 1
          minorseparators | -,$
 stopwordscaseinsensitive | for,the
                     type | 1
                     used | true
(7 rows)

如果 used 参数设置为 False,则只能查看已对分词器应用的参数。

有关详细信息,请参阅READ_CONFIG_FILE

3.5 - 删除分词器配置文件

使用 DELETE_TOKENIZER_CONFIG_FILE 函数删除分词器配置文件。此函数不会删除用户定义的转换函数 (UDTF)。而是仅删除与 UDTF 关联的配置文件。

当参数“已使用 (used)”设置为 False 时,删除分词器配置文件:

=> SELECT v_txtindex.DELETE_TOKENIZER_CONFIG_FILE(USING PARAMETERS proc_oid='45035996274127086');

删除参数“确认 (confirm)”设置为 True 的分词器配置文件。此设置将强制执行配置文件删除操作,即使参数“已使用 (used)”也设置为 True

=> SELECT v_txtindex.DELETE_TOKENIZER_CONFIG_FILE(USING PARAMETERS proc_oid='45035996274126984', confirm='true');

有关详细信息,请参阅DELETE_TOKENIZER_CONFIG_FILE

4 - 自定义词干分析器和分词器的要求

有时,您需要的特定分词或词干抽取行为可能与 Vertica 所提供的不同。在这种情况下,您可以实施自己的自定义“用户定义的扩展 (UDx)”,以取代词干分析器或分词器。有关构建自定义 UDx 的详细信息,请参阅开发用户定义的扩展 (UDx)

在 Vertica 中实现自定义词干分析器或分词器之前,请验证 UDx 扩展是否满足以下要求。

Vertica 词干分析器要求

创建自定义词干分析器时,应遵循以下要求:

  • 必须是用户定义的标量函数 (UDSF) 或 SQL 函数

  • 可使用 C++、Java 或 R 编写

  • 波动性设置为稳定或不可变

支持的数据输入类型

  • Varchar

  • Long varchar

支持的数据输出类型

  • Varchar

  • Long varchar

Vertica 分词器要求

若要创建自定义分词器,请遵循以下要求:

  • 必须是用户定义的转换函数 (UDTF)

  • 可使用 C++、Java 或 R 编写

  • 输入类型必须与输入文本的类型相匹配

支持的数据输入类型

  • Char

  • Varchar

  • Long varchar

  • Varbinary

  • Long varbinary

支持的数据输出类型

  • Varchar

  • Long varchar