使用文本分析器
CREATE SEARCH INDEX
DDL 语句、SEARCH
函数和 TEXT_ANALYZE
函数支持高级文本分析器配置选项。通过了解 BigQuery 的文本分析器及其选项,您可以优化搜索体验。
本文档简要介绍 BigQuery 中提供的不同文本分析器及其配置选项,以及文本分析器如何与 BigQuery 中的搜索搭配使用。如需详细了解文本分析器语法,请参阅文本分析。
文本分析器
BigQuery 支持以下文本分析器:
NO_OP_ANALYZER
LOG_ANALYZER
PATTERN_ANALYZER
NO_OP_ANALYZER
在预处理完您希望完全匹配的数据后,请使用 NO_OP_ANALYZER
。系统不会对文本应用词元化或标准化。由于此分析器不执行词法单元化或标准化,因此不接受任何配置。如需详细了解 NO_OP_ANALYZER
,请参阅 NO_OP_ANALYZER
。
LOG_ANALYZER
LOG_ANALYZER
通过以下方式修改数据:
- 文本将变成小写。
大于 127 的 ASCII 值将保持不变。
文本由以下分隔符拆分为称为“词法单元”的单个术语:
[ ] < > ( ) { } | ! ; , ' " * & ? + / : = @ . - $ % \ _ \n \r \s \t %21 %26 %2526 %3B %3b %7C %7c %20 %2B %2b %3D %3d %2520 %5D %5d %5B %5b %3A %3a %0A %0a %2C %2c %28 %29
如果您不想使用默认分隔符,则可以指定要用作文本分析器选项的分隔符。通过
LOG_ANALYZER
,您可以配置特定的分隔符和令牌过滤器,以便更好地控制搜索结果。如需详细了解使用LOG_ANALYZER
时可用的特定配置选项,请参阅delimiters
分析器选项和token_filters
分析器选项。
PATTERN_ANALYZER
PATTERN_ANALYZER
文本分析器使用正则表达式从文本中提取词法单元。与 PATTERN_ANALYZER
搭配使用的正则表达式引擎和语法为 RE2。PATTERN_ANALYZER
按以下顺序对模式进行词法单元化处理:
- 它会找到与字符串中的模式(从左侧起)匹配的第一个子字符串。这是要包含在输出中的词法单元。
- 它会从输入字符串中移除所有内容(直到第 1 步中发现的子字符串结尾)。
- 它会重复该过程,直到字符串为空。
下表提供了 PATTERN_ANALYZER
词法单元提取示例:
模式 | 输入文本 | 输出令牌 |
---|---|---|
ab | ababab |
|
ab | abacad |
|
[a-z]{2} | abacad |
|
aaa | aaaaa |
|
[a-z]/ | a/b/c/d/e |
|
/[^/]+/ | aa/bb/cc |
|
[0-9]+ | abc | |
(?:/?)[a-z] | /abc |
|
(?:/)[a-z] | /abc |
|
(?:[0-9]abc){3}(?:[a-z]000){2} | 7abc7abc7abcx000y000 |
|
".+" | "cats" 和 "dogs" |
请注意,使用贪婪限定符 + 会匹配文本中可能的最长字符串,导致将“cats”和“dogs”作为文本中的词法单元进行提取。 |
".+?" | "cats" 和 "dogs" |
请注意,使用延迟限定符 +? 会使正则表达式与文本中可能的最短字符串匹配,导致 '"cats"' 和 '"dogs"' 作为文本中的 2 个单独词法单元进行提取。 |
与 SEARCH
函数搭配使用时,使用 PATTERN_ANALYZER
文本分析器可让您更好地控制从文本中提取的词法单元。下表显示了不同的模式和结果如何生成不同的 SEARCH
结果:
模式 | 查询 | 文本 | 文本中的词法单元 | SEARCH(文本、查询) | 说明 |
---|---|---|---|---|---|
abc | abcdef | abcghi |
|
TRUE | ['abcghi'] 中的 'abc' |
cd[a-z] | abcdef | abcghi |
|
FALSE | ['abcghi'] 中的 'cde' |
[a-z]/ | a/b/ | a/b/c/d/ |
|
TRUE | ['a/', 'b/', 'c/', 'd/'] 中的 'a/' 和 ['a/', 'b/', 'c/', 'd/'] 中的 'b/' |
/[^/]+/ | aa/bb/ | aa/bb/cc/ |
|
TRUE | ['/bb/'] 中的 '/bb/' |
/[^/]+/ | bb | aa/bb/cc/ |
|
错误 | 未在查询字词中找到匹配项 |
[0-9]+ | abc | abc123 | 错误 | 未在查询字词中找到匹配项 | |
[0-9]+ | `abc` | abc123 | 错误 | 在查询字词中找不到匹配项 将反引号匹配为反引号,而不是特殊字符。 |
|
[a-z][a-z0-9]*@google\.com | This is my email: test@google.com | test@google.com |
|
TRUE | 'test@google.com' 中的 'test@google.com' |
abc | abc\ abc | abc |
|
TRUE | ['abc'] 中的 'abc' 请注意,'abc abc' 是一个由搜索查询解析器解析后的单个子查询,因为空间已转义。 |
(?i)(?:Abc)(无标准化) | aBcd | Abc |
|
FALSE | ['Abc'] 中的 'aBc' |
(?i)(?:Abc) 标准化: lower_case = true |
aBcd | Abc |
|
TRUE | ['abc'] 中的 'abc' |
(?:/?)abc | bc/abc | /abc/abc/ |
|
TRUE | ['/abc'] 中的 '/abc' |
(?:/?)abc | abc | d/abc |
|
FALSE | ['/abc'] 中的 'abc' |
".+" | "cats" | "cats" 和 "dogs" |
|
FALSE | ['"cats" and "dogs"] 中的 '"cats"' 请注意,使用贪婪限定符 + 会让正则表达式匹配文本中可能的最长字符串,导致将 '"cats" 和 "dogs"' 作为文本中的词法单元进行提取。 |
".+?" | "cats" | "cats" 和 "dogs" |
|
TRUE | ['"cats" and "dogs"] 中的 '"cats"' 请注意,使用延迟限定符 +? 会使正则表达式与文本中尽可能短的字符串匹配,导致 '"cats"'、'"dogs"' 在文本中被提取为 2 个单独的词法单元。 |
示例
以下示例演示如何通过自定义选项使用文本分析来创建搜索索引、提取词法单元并返回搜索结果。
将 LOG_ANALYZER
与 NFKC ICU 标准化和停止字词搭配使用
以下示例使用 NFKC ICU 标准化和停止字词来配置 LOG_ANALYZER
选项。该示例假定以下数据表已填充数据:
CREATE TABLE dataset.data_table( text_data STRING );
如需使用 NFKC ICU 标准化和停止字词列表创建搜索索引,请在 CREATE
SEARCH INDEX
DDL 语句的 analyzer_options
选项中创建 JSON 格式的字符串。如需查看使用 LOG_ANALYZER
创建搜索索引时可用的选项的完整列表,请参阅 LOG_ANALYZER
。在本示例中,我们的停止字词是 "the", "of", "and", "for"
。
CREATE OR REPLACE SEARCH INDEX `my_index` ON `dataset.data_table`(ALL COLUMNS) OPTIONS( analyzer='PATTERN_ANALYZER', analyzer_options= '''{ "token_filters": [ { "normalizer": { "mode": "ICU_NORMALIZE", "icu_normalize_mode": "NFKC", "icu_case_folding": true } }, { "stop_words": ["the", "of", "and", "for"] } ] }''');
根据上例,下表介绍了 text_data
各种值的词法单元提取。请注意,在本文档中,双问号字符 (⁇) 已斜体处理,以区分两个问号 (??):
数据文本 | 索引的词法单元 | 说明 |
---|---|---|
The Quick Brown Fox | ["quick", "brown", "fox"] | LOG_ANALYZER 词法单元化会生成词法单元 ["The", "Quick", "Brown", "Fox"]。 接下来,设为 icu_case_folding = true 的 ICU 标准化会将词法单元小写,以生成 ["the", "quick", "brown", "fox"]最后,停用字词过滤条件会从列表中移除“the”。 |
The Ⓠuick Ⓑrown Ⓕox | ["quick", "brown", "fox"] | LOG_ANALYZER 词法单元化会生成词法单元 ["The", "Ⓠuick", "Ⓑrown", "Ⓕox"]。 接下来,设为 icu_case_folding = true 的 NFKC ICU 标准化会将词法单元小写,以生成 ["the", "quick", "brown", "fox"]最后,停用字词过滤条件会从列表中移除“the”。 |
Ⓠuick⁇Ⓕox | ["quick??fox"] | LOG_ANALYZER 词法单元化会生成词法单元 ["The", "Ⓠuick⁇Ⓕox"]。 接下来,设为 icu_case_folding = true 的 NFKC ICU 标准化并将令牌生成 ["quick??fox"]。请注意,双问号 Unicode 已标准化为 2 个问号 ASCII 字符。最后,停止字词过滤条件不执行任何操作,因为过滤条件列表中没有任何词法单元。 |
现在搜索索引已创建,接下来您可以使用 SEARCH
函数通过搜索索引中指定的相同分析器配置来搜索表。请注意,如果 SEARCH
函数中的分析器配置与搜索索引的配置不匹配,则不会使用搜索索引。使用以下查询:
SELECT SEARCH( analyzer => 'LOG_ANALYZER', analyzer_options => '''{ "token_filters": [ { "normalizer": { "mode": "ICU_NORMALIZE", "icu_normalize_mode": "NFKC", "icu_case_folding": true } }, { "stop_words": ["the", "of", "and", "for"] } ] }''')
替换以下内容:
search_query
:您要搜索的文本。
下表根据不同的搜索文本和不同的 search_query
值演示了各种结果:
text_data | search_query |
结果 | 说明 |
---|---|---|---|
The Quick Brown Fox | "Ⓠuick" |
TRUE |
从文本中提取的词法单元最终列表为 ["quick", "brown", "fox"]。 从文本查询中提取的词法单元的最终列表为 ["quick"]。 列表查询标记都可以在文本词法单元中找到。 |
The Ⓠuick Ⓑrown Ⓕox | "quick" |
TRUE |
从文本中提取的词法单元最终列表为 ["quick", "brown", "fox"]。 从文本查询中提取的词法单元的最终列表为 ["quick"]。 列表查询标记都可以在文本词法单元中找到。 |
Ⓠuick⁇Ⓕox | "quick" |
FALSE |
从文本中提取的词法单元的最终列表为 ["quick??fox"]。 从文本查询中提取的词法单元的最终列表为 ["quick"]。 “quick”不在文本的词法单元列表中。 |
Ⓠuick⁇Ⓕox | "quick⁇fox" |
TRUE |
从文本中提取的词法单元的最终列表为 ["quick??fox"]。 从文本查询中提取的词法单元的最终列表为 ["quick??fox"]。 “quick??fox”位于文本的词法单元列表中。 |
Ⓠuick⁇Ⓕox | "`quick⁇fox`" |
FALSE |
在 LOG_ANALYZER 中,反引号需要完全匹配文本。 |
PATTERN_ANALYZER
,用于具有停止字词的 IPv4 搜索
以下示例将 PATTERN_ANALYZER
文本分析器配置为搜索特定模式,同时过滤特定停止字词。在此示例中,模式与 IPv4 地址匹配,并忽略 localhost 值 (127.0.0.1
)。
此示例假定下表填充了数据:
CREATE TABLE dataset.data_table( text_data STRING );
如需创建搜索索引 pattern
选项和停止字词列表,请在 CREATE SEARCH
INDEX
DDL 语句的 analyzer_options
选项中创建 JSON 格式的字符串
如需查看使用 PATTERN_ANALYZER
创建搜索索引时可用的选项的完整列表,请参阅 PATTERN_ANALYZER
。在本示例中,我们的停止字词是 localhost 地址 127.0.0.1
。
CREATE SEARCH INDEX my_index ON dataset.data_table(text_data) OPTIONS (analyzer = 'PATTERN_ANALYZER', analyzer_options = '''{ "patterns": [ "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" ], "token_filters": [ { "stop_words": [ "127.0.0.1" ] } ] }''' );
将正则表达式与 analyzer_options
搭配使用时,请包含三个前导 \
符号,以正确转义包含 \
符号的正则表达式,例如 \d
或 \b
。
下表介绍了 text_data
各种值的词法单元化选项
数据文本 | 索引的词法单元 | 说明 |
---|---|---|
abc192.168.1.1def 172.217.20.142 | ["192.168.1.1", "172.217.20.142"] | 即使地址和文本之间没有空格,IPv4 模式也会捕获 IPv4 地址。 |
104.24.12.10abc 127.0.0.1 | ["104.24.12.10"] | “127.0.0.1”已被滤除,因为它位于停止字词列表中。 |
搜索索引现已创建,您可以使用 SEARCH
函数根据 analyzer_options
中指定的词法单元化来搜索表。使用以下查询:
SELECT SEARCH(dataset.data_table.text_data "search_data", analyzer => 'PATTERN_ANALYZER', analyzer_options => '''{ "patterns": [ "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" ], "token_filters": [ { "stop_words": [ "127.0.0.1" ] } ] }''' );
替换以下内容:
search_query
:您要搜索的文本。
下表根据不同的搜索文本和不同的 search_query
值演示了各种结果:
text_data | search_query |
结果 | 说明 |
---|---|---|---|
128.0.0.2 | "127.0.0.1" | 错误 | 查询中没有搜索词法单元。 查询会经过文本分析器,它会过滤掉“127.0.0.1”词法单元。 |
abc192.168.1.1def 172.217.20.142 | "192.168.1.1abc" | TRUE | 从查询中提取的词法单元列表为 ["192.168.1.1"]。 从文本中提取的词法单元列表为 ["192.168.1.1", "172.217.20.142"]。 |
abc192.168.1.1def 172.217.20.142 | "`192.168.1.1`" | TRUE | 从查询中提取的词法单元列表为 ["192.168.1.1"]。 从文本中提取的词法单元列表为 ["192.168.1.1", "172.217.20.142"]。 请注意,反引号被视为 PATTERN_ANALYZER 的常规字符。 |
后续步骤
- 如需简要了解搜索索引用例、价格、所需权限和限制,请参阅 BigQuery 搜索简介。
- 如需了解如何高效搜索已编入索引的列,请参阅使用索引进行搜索。