Solr索引:分词器完整指南与实例详解

Solr索引:分词器完整指南与实例详解

分词器负责将字段数据分解为词汇单元或tokens。每个token(通常)是文本中字符的子序列。分析器知道它配置的字段,但分词器不知道。分词器从字符流(Reader)中读取并产生token对象序列(TokenStream)。

分词器基本概念

工作原理

  • 输入流中的字符如空格或其他分隔符可能被丢弃
  • 它们也可能被添加或替换,如将别名或缩写映射到标准化形式
  • token包含除文本值外的各种元数据,如token在字段中出现的位置

重要注意事项

由于分词器可能产生与输入文本不同的token,您不应假设:

  • token的文本与字段中出现的文本相同
  • token的长度与原始文本相同
  • 多个token可能具有相同位置或引用原始文本中的相同偏移量

在使用token元数据进行搜索结果高亮等功能时要记住这一点。

分词器配置语法

基本配置格式

在schema的<fieldType>中配置分词器,作为<analyzer>的子元素:

使用符号名称(推荐)

1
2
3
4
5
6
<fieldType name="text" class="solr.TextField">
<analyzer type="index">
<tokenizer name="standard"/>
<filter name="lowercase"/>
</analyzer>
</fieldType>

使用类名(遗留方式)

1
2
3
4
5
6
<fieldType name="text" class="solr.TextField">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>

参数传递

通过在<tokenizer>元素上设置属性向分词器工厂传递参数:

使用符号名称

1
2
3
4
5
<fieldType name="semicolonDelimited" class="solr.TextField">
<analyzer type="query">
<tokenizer name="pattern" pattern="; "/>
</analyzer>
</fieldType>

使用类名(遗留方式)

1
2
3
4
5
<fieldType name="semicolonDelimited" class="solr.TextField">
<analyzer type="query">
<tokenizer class="solr.PatternTokenizerFactory" pattern="; "/>
</analyzer>
</fieldType>

CharFilter vs TokenFilter的选择

决策因素

选择使用CharFilter还是TokenFilter主要取决于:

  • 您使用的Tokenizer
  • 是否需要预处理字符流

使用场景

例如,假设您对StandardTokenizer的整体工作方式很满意,但想自定义某些特定字符的行为。您可以使用JFlex修改规则并重新构建自己的tokenizer,但在tokenization之前使用CharFilter映射一些字符可能更容易。

内置分词器详解

1. Standard Tokenizer

功能特点

  • 将文本字段分解为token,将空格和标点作为分隔符
  • 分隔符字符被丢弃,以下情况除外:
    • 未跟空格的句点保留为token的一部分,包括Internet域名
    • “@”字符是token分割标点符号,因此电子邮件地址不会保留为单个token
  • 注意:单词在连字符处分割

Unicode支持

支持Unicode标准附录UAX#29词边界,包含以下token类型:
<ALPHANUM>, <NUM>, <SOUTHEAST_ASIAN>, <IDEOGRAPHIC>, <HIRAGANA>

配置参数

Factory class: solr.StandardTokenizerFactory

Arguments:

  • maxTokenLength: 可选,默认255。Solr忽略超过指定字符数的token

使用示例

1
2
3
4
5
6
7
8
9
<!-- 使用符号名称 -->
<analyzer>
<tokenizer name="standard"/>
</analyzer>

<!-- 使用类名(遗留) -->
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
</analyzer>

输入: “Please, email john.doe@foo.com by 03-09, re: m37-xq.”
输出: “Please”, “email”, “john.doe”, “foo.com”, “by”, “03”, “09”, “re”, “m37”, “xq”

2. Classic Tokenizer

功能特点

保持与Solr 3.1及之前版本相同的行为,不使用Unicode标准附录UAX#29词边界规则。

特殊处理

  • 未跟空格的句点保留为token的一部分
  • 单词在连字符处分割,除非单词中有数字,此时token不分割,数字和连字符被保留
  • 识别Internet域名和电子邮件地址并保留为单个token

配置参数

Factory class: solr.ClassicTokenizerFactory

Arguments:

  • maxTokenLength: 可选,默认255

使用示例

1
2
3
<analyzer>
<tokenizer name="classic"/>
</analyzer>

输入: “Please, email john.doe@foo.com by 03-09, re: m37-xq.”
输出: “Please”, “email”, “john.doe@foo.com“, “by”, “03-09”, “re”, “m37-xq”

3. Keyword Tokenizer

功能特点

将整个文本字段作为单个token处理。

配置参数

Factory class: solr.KeywordTokenizerFactory

Arguments:

  • maxTokenLen: 可选,默认256。分词器发出的最大token长度

使用示例

1
2
3
<analyzer>
<tokenizer name="keyword"/>
</analyzer>

输入: “Please, email john.doe@foo.com by 03-09, re: m37-xq.”
输出: “Please, email john.doe@foo.com by 03-09, re: m37-xq.”

4. Letter Tokenizer

功能特点

从连续字母的字符串创建token,丢弃所有非字母字符。

配置参数

Factory class: solr.LetterTokenizerFactory

Arguments:

  • maxTokenLen: 可选,默认255

使用示例

1
2
3
<analyzer>
<tokenizer name="letter"/>
</analyzer>

输入: “I can’t.”
输出: “I”, “can”, “t”

5. Lower Case Tokenizer

功能特点

通过在非字母处分隔然后将所有字母转换为小写来tokenize输入流。丢弃空格和非字母。

配置参数

Factory class: solr.LowerCaseTokenizerFactory

Arguments:

  • maxTokenLen: 可选,默认255

使用示例

1
2
3
<analyzer>
<tokenizer name="lowercase"/>
</analyzer>

输入: “I just *LOVE* my iPhone!”
输出: “i”, “just”, “love”, “my”, “iphone”

6. N-Gram Tokenizer

功能特点

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

配置参数

Factory class: solr.NGramTokenizerFactory

Arguments:

  • minGramSize: 可选,默认1。最小n-gram大小,必须>0
  • maxGramSize: 可选,默认2。最大n-gram大小,必须>=minGramSize

使用示例

1
2
3
4
<!-- 默认行为 -->
<analyzer>
<tokenizer name="nGram"/>
</analyzer>

输入: “hey man”
输出: “h”, “e”, “y”, “ “, “m”, “a”, “n”, “he”, “ey”, “y “, “ m”, “ma”, “an”

1
2
3
4
<!-- n-gram大小范围4到5 -->
<analyzer>
<tokenizer name="nGram" minGramSize="4" maxGramSize="5"/>
</analyzer>

输入: “bicycle”
输出: “bicy”, “bicyc”, “icyc”, “icycl”, “cycl”, “cycle”, “ycle”

7. Edge N-Gram Tokenizer

功能特点

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

配置参数

Factory class: solr.EdgeNGramTokenizerFactory

Arguments:

  • minGramSize: 可选,默认1。最小n-gram大小,必须>0
  • maxGramSize: 可选,默认1。最大n-gram大小,必须>=minGramSize

使用示例

1
2
3
4
<!-- 默认行为 -->
<analyzer>
<tokenizer name="edgeNGram"/>
</analyzer>

输入: “babaloo”
输出: “b”

1
2
3
4
<!-- 边缘n-gram范围2到5 -->
<analyzer>
<tokenizer name="edgeNGram" minGramSize="2" maxGramSize="5"/>
</analyzer>

输入: “babaloo”
输出: “ba”, “bab”, “baba”, “babal”

8. ICU Tokenizer

功能特点

处理多语言文本并根据其脚本属性进行适当的tokenization。

高级配置

可以通过指定每个脚本的规则文件来自定义此分词器的行为。使用rulefiles参数,格式为:四字母ISO 15924脚本代码,后跟冒号,然后是资源路径。

配置参数

Factory class: solr.ICUTokenizerFactory

Arguments:

  • rulefile: 可选。逗号分隔的code:rulefile对列表
  • cjkAsWords: 可选,默认true。如果为true,CJK文本将进行基于字典的分割
  • myanmarAsWords: 可选,默认true。如果为true,缅甸文本将进行基于字典的分割

使用示例

1
2
3
4
5
6
7
8
9
10
<!-- 无自定义 -->
<analyzer>
<tokenizer name="icu"/>
</analyzer>

<!-- 使用自定义规则文件 -->
<analyzer>
<tokenizer name="icu"
rulefiles="Latn:my.Latin.rules.rbbi,Cyrl:my.Cyrillic.rules.rbbi"/>
</analyzer>

重要提醒: 要使用此分词器,必须向Solr的classpath添加额外的.jar文件。

9. Path Hierarchy Tokenizer

功能特点

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

配置参数

Factory class: solr.PathHierarchyTokenizerFactory

Arguments:

  • delimiter: 必需。指定文件路径分隔符
  • replace: 必需。指定tokenized输出中使用的分隔符
  • reverse: 可选,默认false。如果为true,以”反向”顺序构建路径层次结构
  • skip: 可选,默认0。从每个发出的token中删除的最左侧(或最右侧,如果reverse=true)路径元素的数量

使用示例

1
2
3
4
5
6
<!-- 默认行为 -->
<fieldType name="text_path" class="solr.TextField">
<analyzer>
<tokenizer name="pathHierarchy" delimiter="\" replace="/"/>
</analyzer>
</fieldType>

输入: “c:\usr\local\apache”
输出: “c:”, “c:/usr”, “c:/usr/local”, “c:/usr/local/apache”

1
2
3
4
5
6
<!-- 反向顺序 -->
<fieldType name="text_path" class="solr.TextField">
<analyzer>
<tokenizer name="pathHierarchy" delimiter="." replace="." reverse="true"/>
</analyzer>
</fieldType>

输入: “www.site.co.uk
输出: “www.site.co.uk“, “site.co.uk”, “co.uk”, “uk”

10. Regular Expression Pattern Tokenizer

功能特点

使用Java正则表达式将输入文本流分解为token。表达式可以解释为分隔符或匹配模式。

配置参数

Factory class: solr.PatternTokenizerFactory

Arguments:

  • pattern: 必需。正则表达式,如java.util.regex.Pattern中定义
  • group: 可选,默认-1。指定要作为token提取的正则表达式组

使用示例

1
2
3
4
<!-- 逗号分隔列表 -->
<analyzer>
<tokenizer name="pattern" pattern="\s*,\s*"/>
</analyzer>

输入: “fee,fie, foe , fum, foo”
输出: “fee”, “fie”, “foe”, “fum”, “foo”

1
2
3
4
<!-- 提取简单的大写单词 -->
<analyzer>
<tokenizer name="pattern" pattern="[A-Z][A-Za-z]*" group="0"/>
</analyzer>

输入: “Hello. My name is Inigo Montoya. You killed my father. Prepare to die.”
输出: “Hello”, “My”, “Inigo”, “Montoya”, “You”, “Prepare”

11. UAX29 URL Email Tokenizer

功能特点

将文本字段分解为token,将空格和标点作为分隔符,但有以下特殊处理:

  • 保留不跟空格的句点
  • 识别并保留Internet域名、电子邮件地址、各种URL和IP地址

支持的内容类型

  • Internet域名(包含在IANA根区域数据库中验证的顶级域名)
  • 电子邮件地址
  • file://, http(s)://, 和 ftp:// URLs
  • IPv4和IPv6地址

配置参数

Factory class: solr.UAX29URLEmailTokenizerFactory

Arguments:

  • maxTokenLength: 可选,默认255

使用示例

1
2
3
<analyzer>
<tokenizer name="uax29URLEmail"/>
</analyzer>

输入: “Visit http://accarol.com/contact.htm?from=external&a=10 or e-mail bob.cratchet@accarol.com
输出: “Visit”, “http://accarol.com/contact.htm?from=external&a=10“, “or”, “e”, “mail”, “bob.cratchet@accarol.com

12. White Space Tokenizer

功能特点

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

配置参数

Factory class: solr.WhitespaceTokenizerFactory

Arguments:

  • rule: 可选,默认java。指定如何定义空格以进行tokenization
    • java: 使用Character.isWhitespace(int)
    • unicode: 使用Unicode的WHITESPACE属性
  • maxTokenLen: 可选,默认255

使用示例

1
2
3
<analyzer>
<tokenizer name="whitespace" rule="java"/>
</analyzer>

输入: “To be, or what?”
输出: “To”, “be,”, “or”, “what?”

分词器选择指南

1. 通用文本分析

  • Standard Tokenizer: 适合大多数西方语言的通用分析
  • Classic Tokenizer: 需要保持与旧版本兼容时使用

2. 精确匹配

  • Keyword Tokenizer: 需要将整个字段作为单个token时使用
  • WhitespaceTokenizer: 只需要基本的空格分割时使用

3. 搜索建议和自动完成

  • EdgeNGramTokenizer: 适合前缀匹配和搜索建议
  • NGramTokenizer: 适合部分匹配搜索

4. 特殊格式数据

  • PathHierarchyTokenizer: 适合文件路径或分层数据
  • PatternTokenizer: 适合有特定格式的数据
  • UAX29URLEmailTokenizer: 适合包含URL和邮箱的内容

5. 多语言内容

  • ICUTokenizer: 适合复杂的多语言文本处理

性能优化建议

1. 选择合适的分词器

  • 避免过于复杂的正则表达式
  • N-gram分词器会产生大量token,影响索引大小和性能
  • ICU分词器功能强大但相对较慢

2. 参数调优

  • 适当设置maxTokenLength避免过长token
  • N-gram的minGramSize和maxGramSize需要根据实际需求平衡

3. 测试和验证

  • 使用Solr管理界面的分析工具测试分词效果
  • 监控索引大小和查询性能的变化

分词器是文本分析流水线的第一步,选择和配置合适的分词器对搜索质量和性能都有重要影响。根据具体的数据特点和搜索需求选择最适合的分词器配置。

© 2025 Solr Community of China All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero