分词器

分词器负责将字段数据分解为词汇单元或标记

每个标记(通常)是文本中字符的子序列。分析器知道它配置的字段,但分词器不知道。分词器从字符流(一个Reader)读取,并生成一系列标记对象(一个TokenStream)。

输入流中的空格或其他分隔符等字符可能会被丢弃。它们也可能被添加或替换,例如将别名或缩写映射到规范化形式。

除了文本值之外,标记还包含各种元数据,例如标记在字段中出现的位置。由于分词器可能会产生与输入文本不同的标记,因此您不应假设标记的文本与字段中出现的文本相同,或者其长度与原始文本相同。也可能存在多个标记在原始文本中具有相同的位置或引用相同的偏移量。如果您使用标记元数据来处理诸如突出显示字段文本中的搜索结果之类的操作,请记住这一点。

关于分词器

您可以使用 <tokenizer> 元素(作为 <analyzer> 的子元素)在 模式中为文本字段类型配置分词器

  • 使用名称

  • 使用类名(旧版)

<fieldType name="text" class="solr.TextField">
  <analyzer type="index">
    <tokenizer name="standard"/>
    <filter name="lowercase"/>
  </analyzer>
</fieldType>
<fieldType name="text" class="solr.TextField">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

name/class 属性命名一个工厂类,该类将在需要时实例化一个分词器对象。分词器工厂类实现 org.apache.lucene.analysis.TokenizerFactory。TokenizerFactory 的 create() 方法接受一个 Reader 并返回一个 TokenStream。当 Solr 创建分词器时,它会传递一个 Reader 对象,该对象提供文本字段的内容。

可以通过在 <tokenizer> 元素上设置属性将参数传递给分词器工厂。

  • 使用名称

  • 使用类名(旧版)

<fieldType name="semicolonDelimited" class="solr.TextField">
  <analyzer type="query">
    <tokenizer name="pattern" pattern="; "/>
  </analyzer>
</fieldType>
<fieldType name="semicolonDelimited" class="solr.TextField">
  <analyzer type="query">
    <tokenizer class="solr.PatternTokenizerFactory" pattern="; "/>
  </analyzer>
</fieldType>

何时使用 CharFilter 与 TokenFilter

有几对 CharFilter 和 TokenFilter 具有相关(即,MappingCharFilterASCIIFoldingFilter)或几乎相同(即,PatternReplaceCharFilterFactoryPatternReplaceFilterFactory)的功能,并且可能并不总是很明显哪一个是最优选择。

关于使用哪一个的决定在很大程度上取决于您正在使用的分词器,以及是否需要预处理字符流。

例如,假设你有一个分词器,如 StandardTokenizer,并且你对它的整体工作方式非常满意,但你想自定义某些特定字符的行为。你可以修改规则并使用 JFlex 重新构建你自己的分词器,但使用 CharFilter 在分词之前简单地映射一些字符可能更容易。

以下章节描述了此 Solr 版本中包含的分词器工厂类。

标准分词器

此分词器将文本字段拆分为词元,将空格和标点符号视作分隔符。分隔符字符会被丢弃,但以下情况除外:

  • 不跟空格的点号(句点)会被保留为词元的一部分,包括互联网域名。

  • “@”字符属于分词标点符号集,因此电子邮件地址不会被保留为单个词元。

请注意,单词会在连字符处拆分。

标准分词器支持 Unicode 标准附件 UAX#29 单词边界,并具有以下词元类型:<ALPHANUM><NUM><SOUTHEAST_ASIAN><IDEOGRAPHIC><HIRAGANA>

工厂类: solr.StandardTokenizerFactory

参数

maxTokenLength

可选

默认值:255

Solr 会忽略超过 maxTokenLength 指定字符数的词元。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="standard"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.StandardTokenizerFactory"/>
</analyzer>

输入: "请于 03-09 前发送电子邮件至 [email protected],主题:m37-xq。"

输出: "请于", "发送电子邮件至", "john.doe", "foo.com", "于", "03", "09", "主题", "m37", "xq"

经典分词器

经典分词器保留了 Solr 3.1 及更早版本中标准分词器的行为。它不使用标准分词器使用的 Unicode 标准附件 UAX#29 单词边界规则。此分词器将文本字段拆分为词元,将空格和标点符号视作分隔符。分隔符字符会被丢弃,但以下情况除外:

  • 不跟空格的点号(句点)会被保留为词元的一部分。

  • 单词会在连字符处拆分,除非单词中有数字,在这种情况下,词元不会拆分,数字和连字符会被保留。

  • 识别互联网域名和电子邮件地址,并将其保留为单个词元。

工厂类: solr.ClassicTokenizerFactory

参数

maxTokenLength

可选

默认值:255

Solr 会忽略超过 maxTokenLength 指定字符数的词元。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="classic"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.ClassicTokenizerFactory"/>
</analyzer>

输入: "请于 03-09 前发送电子邮件至 [email protected],主题:m37-xq。"

输出: "请于", "发送电子邮件至", "[email protected]", "于", "03-09", "主题", "m37-xq"

关键字分词器

此分词器将整个文本字段视为单个词元。

工厂类: solr.KeywordTokenizerFactory

参数

maxTokenLen

可选

默认值:256

分词器将发出的最大词元长度。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="keyword"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.KeywordTokenizerFactory"/>
</analyzer>

输入: "请于 03-09 前发送电子邮件至 [email protected],主题:m37-xq。"

输出: "请于 03-09 前发送电子邮件至 [email protected],主题:m37-xq。"

字母分词器

此分词器从连续的字母字符串创建词元,丢弃所有非字母字符。

工厂类: solr.LetterTokenizerFactory

参数

maxTokenLen

可选

默认值:255

分词器将发出的最大词元长度。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="letter"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.LetterTokenizerFactory"/>
</analyzer>

输入: "我不能。"

输出: "我", "不能"

小写分词器

通过在非字母处分隔输入流,然后将所有字母转换为小写来对输入流进行分词。空格和非字母会被丢弃。

工厂类: solr.LowerCaseTokenizerFactory

参数

maxTokenLen

可选

默认值:255

分词器将发出的最大词元长度。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="lowercase"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.LowerCaseTokenizerFactory"/>
</analyzer>

输入: "我真的*爱*我的iPhone!"

输出: "我", "真的", "爱", "我的", "iphone"

N-Gram 分词器

读取字段文本并生成给定范围大小的 n-gram 词元。

工厂类: solr.NGramTokenizerFactory

参数

minGramSize

可选

默认值:1

最小 n-gram 大小,必须 > 0。

maxGramSize

可选

默认值:2

最大 n-gram 大小,必须 >= minGramSize

示例

默认行为。请注意,此分词器在整个字段上操作。它不会在空格处断开字段。因此,空格字符会包含在编码中。

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="nGram"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.NGramTokenizerFactory"/>
</analyzer>

输入: "嘿 伙计"

输出: "嘿", " ", "伙", "计", "嘿 ", " 伙", "伙计"

示例

n-gram 大小范围为 4 到 5

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="nGram" minGramSize="4" maxGramSize="5"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.NGramTokenizerFactory" minGramSize="4" maxGramSize="5"/>
</analyzer>

输入: "自行车"

输出: "自行", "自行车", "行车", "自行车"

边缘 N-Gram 分词器

读取字段文本并生成给定范围大小的边缘 n-gram 词元。

工厂类: solr.EdgeNGramTokenizerFactory

参数

minGramSize

可选

默认值:1

最小 n-gram 大小,必须 > 0。

maxGramSize

可选

默认值:1

最大 n-gram 大小,必须 >= minGramSize

示例

默认行为(最小和最大值默认为 1)

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="edgeNGram"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.EdgeNGramTokenizerFactory"/>
</analyzer>

输入: "babaloo"

输出: "b"

示例

边缘 n-gram 范围为 2 到 5

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="edgeNGram" minGramSize="2" maxGramSize="5"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.EdgeNGramTokenizerFactory" minGramSize="2" maxGramSize="5"/>
</analyzer>

输入: "babaloo"

输出: "ba", "bab", "baba", "babal"

ICU 分词器

此分词器处理多语言文本,并根据其脚本属性对其进行适当的分词。

你可以通过指定 每个脚本的规则文件来自定义此分词器的行为。要添加每个脚本的规则,请添加一个 rulefiles 参数,其中应包含一个以逗号分隔的 代码:规则文件 对列表,格式如下:四个字母的 ISO 15924 脚本代码,后跟一个冒号,然后是资源路径。例如,要为拉丁语(脚本代码“Latn”)和西里尔语(脚本代码“Cyrl”)指定规则,你将输入 Latn:my.Latin.rules.rbbi,Cyrl:my.Cyrillic.rules.rbbi

solr.ICUTokenizerFactory 的默认配置提供 UAX#29 单词断开规则分词(如 solr.StandardTokenizer),但也包括希伯来语的自定义调整(专门处理双引号和单引号)、高棉语、老挝语和缅甸语的音节分词,以及 CJK 字符的基于字典的单词分割。

工厂类: solr.ICUTokenizerFactory

参数

rulefile

可选

默认值:无

一个以逗号分隔的 代码:规则文件 对列表,格式如下:四个字母的 ISO 15924 脚本代码,后跟一个冒号,然后是资源路径。

cjkAsWords

可选

默认值:true

如果为 true,CJK 文本将进行基于字典的分割,所有汉字+平假名+片假名单词都将标记为 IDEOGRAPHIC。否则,文本将根据 UAX#29 默认值进行分割。

myanmarAsWords

可选

默认值:true

如果为 true,缅甸语文本将进行基于字典的分割,否则将分词为音节。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <!-- no customization -->
  <tokenizer name="icu"/>
</analyzer>
<analyzer>
  <!-- no customization -->
  <tokenizer class="solr.ICUTokenizerFactory"/>
</analyzer>
  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="icu"
             rulefiles="Latn:my.Latin.rules.rbbi,Cyrl:my.Cyrillic.rules.rbbi"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.ICUTokenizerFactory"
             rulefiles="Latn:my.Latin.rules.rbbi,Cyrl:my.Cyrillic.rules.rbbi"/>
</analyzer>

要使用此分词器,你必须向 Solr 的类路径中添加额外的 .jar 文件(如 安装插件 部分所述)。有关你需要添加哪些 jar 文件的信息,请参阅 solr/modules/analysis-extras/README.md

路径层次结构分词器

此分词器从文件路径层次结构创建同义词。

工厂类: solr.PathHierarchyTokenizerFactory

参数

delimiter

必需

默认值:无

你可以指定文件路径分隔符,并将其替换为你提供的分隔符。这对于使用反斜杠分隔符非常有用。

replace

必需

默认值:无

指定 Solr 在分词输出中使用的分隔符字符。

reverse

可选

默认值:false

如果为 true,则将分词器行为切换为以“反向”顺序构建路径层次结构。这通常对于标记 URL 非常有用。

skip

可选

默认值:0

从每个发出的词元中删除的最左侧(如果 reverse=true,则为最右侧)路径元素的数量。

示例

默认行为

  • 使用名称

  • 使用类名(旧版)

<fieldType name="text_path" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer name="pathHierarchy" delimiter="\" replace="/"/>
  </analyzer>
</fieldType>
<fieldType name="text_path" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="\" replace="/"/>
  </analyzer>
</fieldType>

输入: "c:\usr\local\apache"

输出: "c:", "c:/usr", "c:/usr/local", "c:/usr/local/apache"

示例

反向顺序

  • 使用名称

  • 使用类名(旧版)

<fieldType name="text_path" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer name="pathHierarchy" delimiter="." replace="." reverse="true"/>
  </analyzer>
</fieldType>
<fieldType name="text_path" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="." replace="." reverse="true"/>
  </analyzer>
</fieldType>

输入: "www.site.co.uk"

输出: "www.site.co.uk", "site.co.uk", "co.uk", "uk"

正则表达式模式分词器

此分词器使用 Java 正则表达式将输入文本流分解为词元。由 pattern 参数提供的表达式可以解释为分隔词元的分隔符,也可以解释为匹配应从文本中提取为词元的模式。

有关 Java 正则表达式语法的更多信息,请参阅 java.util.regex.Pattern 的 Javadocs

工厂类: solr.PatternTokenizerFactory

参数

pattern

必需

默认值:无

正则表达式,如 java.util.regex.Pattern 中定义的那样。

group

可选

默认值:-1

指定要提取为词元的正则表达式组。值 -1 表示正则表达式应被视为分隔词元的分隔符。非负组号(>= 0)表示与该正则表达式组匹配的字符序列应转换为词元。组零指的是整个正则表达式,大于零的组指的是正则表达式的带括号的子表达式,从左到右计数。

示例

一个以逗号分隔的列表。词元由零个或多个空格、一个逗号和零个或多个空格的序列分隔。

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="pattern" pattern="\s*,\s*"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.PatternTokenizerFactory" pattern="\s*,\s*"/>
</analyzer>

输入: "fee,fie, foe , fum, foo"

输出: "fee", "fie", "foe", "fum", "foo"

示例

提取简单的、首字母大写的单词。至少一个大写字母后跟零个或多个任意大小写字母的序列被提取为一个词元。

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="pattern" pattern="[A-Z][A-Za-z]*" group="0"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.PatternTokenizerFactory" pattern="[A-Z][A-Za-z]*" group="0"/>
</analyzer>

输入: "你好。我叫伊尼戈·蒙托亚。你杀了我父亲。准备去死。"

输出: "你好", "我叫", "伊尼戈", "蒙托亚", "你", "准备"

示例

提取以“SKU”、“Part”或“Part Number”开头(区分大小写)、可选分号分隔的零件编号。零件编号必须全部为数字,并且可选地包含连字符。正则表达式捕获组通过从左到右计数左括号来编号。第 3 组是子表达式“[0-9-]”,它匹配一个或多个数字或连字符。

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="pattern" pattern="(SKU|Part(\sNumber)?):?\s(\[0-9-\]+)" group="3"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.PatternTokenizerFactory" pattern="(SKU|Part(\sNumber)?):?\s(\[0-9-\]+)" group="3"/>
</analyzer>

输入: "SKU: 1234, Part Number 5678, Part: 126-987"

输出 "1234", "5678", "126-987"

简化正则表达式模式分词器

此分词器类似于上面描述的 PatternTokenizerFactory,但使用 Lucene RegExp 模式匹配为输入流构造不同的词元。语法比 PatternTokenizerFactory 更受限制,但分词速度要快得多。

工厂类: solr.SimplePatternTokenizerFactory

参数

pattern

必需

默认值:无

正则表达式,如 RegExp javadocs 中定义的那样,用于标识要包含在词元中的字符。匹配是贪婪的,因此创建给定点匹配的最长词元。永远不会创建空词元。

determinizeWorkLimit

可选

默认值:10000

从正则表达式计算出的确定自动机的总状态数的限制。

示例

匹配由简单空格字符分隔的词元

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="simplePattern" pattern="[^ \t\r\n]+"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.SimplePatternTokenizerFactory" pattern="[^ \t\r\n]+"/>
</analyzer>

简化正则表达式模式分割分词器

此分词器类似于上面描述的 SimplePatternTokenizerFactory,但使用 Lucene RegExp 模式匹配来标识应用于分割词元的字符序列。语法比 PatternTokenizerFactory 更受限制,但分词速度要快得多。

工厂类: solr.SimplePatternSplitTokenizerFactory

参数

pattern

必需

默认值:无

正则表达式,由 RegExp javadocs 定义,用于识别应分割标记的字符。匹配是贪婪的,因此在给定点匹配的最长标记分隔符将被匹配。永远不会创建空标记。

determinizeWorkLimit

可选

默认值:10000

从正则表达式计算出的确定自动机的总状态数的限制。

示例

匹配由简单空格字符分隔的词元

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="simplePatternSplit" pattern="[ \t\r\n]+"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.SimplePatternSplitTokenizerFactory" pattern="[ \t\r\n]+"/>
</analyzer>

UAX29 URL 邮箱分词器

此分词器将文本字段拆分为词元,将空格和标点符号视作分隔符。分隔符字符会被丢弃,但以下情况除外:

  • 不跟空格的点号(句点)会被保留为词元的一部分。

  • 单词会在连字符处拆分,除非单词中有数字,在这种情况下,词元不会拆分,数字和连字符会被保留。

  • 识别并保留以下内容为单个标记:

    • 当分词器生成时,根据 IANA 根区域数据库 中的白名单验证的包含顶级域名的 Internet 域名。

    • 电子邮件地址

    • file://http(s)://ftp:// URL

    • IPv4 和 IPv6 地址

UAX29 URL 邮箱分词器支持 Unicode 标准附件 UAX#29 的词边界,具有以下标记类型:<ALPHANUM><NUM><URL><EMAIL><SOUTHEAST_ASIAN><IDEOGRAPHIC><HIRAGANA>

工厂类: solr.UAX29URLEmailTokenizerFactory

参数

maxTokenLength

可选

默认值:255

Solr 会忽略超过 maxTokenLength 指定字符数的词元。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="uax29URLEmail"/>
</analyzer>
<analyzer>
  <tokenizer class="solr.UAX29URLEmailTokenizerFactory"/>
</analyzer>

输出: "访问", "http://accarol.com/contact.htm?from=external&a=10", "或", "发送", "电子", "[email protected]"

空格分词器

简单的分词器,它在空格上分割文本流,并将非空格字符序列作为标记返回。请注意,任何标点符号包含在标记中。

工厂类: solr.WhitespaceTokenizerFactory

参数

规则

可选

默认值:java

指定如何为分词定义空格。有效值

maxTokenLen

可选

默认值:255

分词器将发出的最大词元长度。

示例

  • 使用名称

  • 使用类名(旧版)

<analyzer>
  <tokenizer name="whitespace" rule="java" />
</analyzer>
<analyzer>
  <tokenizer class="solr.WhitespaceTokenizerFactory" rule="java" />
</analyzer>

输入: "生存还是毁灭,这是一个问题?"

输出: "生存", "还是毁灭,", "这是", "一个问题?"

OpenNLP 分词器和 OpenNLP 过滤器

有关使用 OpenNLP 分词器以及有关可用 OpenNLP 标记过滤器的信息,请参阅 OpenNLP 集成