Solr索引:分析器

分析器检查字段的文本并生成token流。

分析器在Solr的schema中被指定为<fieldType>元素的子元素。

在正常使用中,只有solr.TextFieldsolr.SortableTextField类型的字段才会指定分析器。
配置分析器的最简单方法是使用单个<analyzer>元素,其class属性是完全限定的Java类名。
命名的类必须派生自org.apache.lucene.analysis.Analyzer
例如:

1
2
3
<fieldType name="nametext" class="solr.TextField">
<analyzer class="org.apache.lucene.analysis.core.WhitespaceAnalyzer"/>
</fieldType>

在这种情况下,单个类WhitespaceAnalyzer负责分析命名文本字段的内容并发出相应的token。
对于简单情况,如纯英语散文,像这样的单个分析器类可能就足够了。
但通常需要对字段内容进行更复杂的分析。

即使是最复杂的分析需求通常也可以分解为一系列离散的、相对简单的处理步骤。
如你将很快发现的,Solr发行版提供了大量的分词器和过滤器选择,涵盖了你可能遇到的大多数场景。
设置分析器链非常直接;你指定一个简单的<analyzer>元素(没有class属性),其子元素命名用于分词器和过滤器的工厂类,按照你希望它们运行的顺序。

例如:

使用名称:

1
2
3
4
5
6
7
8
<fieldType name="nametext" class="solr.TextField">
<analyzer>
<tokenizer name="standard"/>
<filter name="lowercase"/>
<filter name="stop"/>
<filter name="englishPorter"/>
</analyzer>
</fieldType>

分词器和过滤器工厂类通过它们的符号名称(SPI名称)引用。
这里,name=”standard”指向org.apache.lucene.analysis.standard.StandardTokenizerFactory

使用类名(遗留):

1
2
3
4
5
6
7
8
<fieldType name="nametext" class="solr.TextField">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory"/>
<filter class="solr.EnglishPorterFilterFactory"/>
</analyzer>
</fieldType>

注意org.apache.lucene.analysis包中的类可以在这里用solr.前缀的简写形式引用。

在这种情况下,<analyzer>元素上没有指定Analyzer类。
相反,一系列更专门的类被连接在一起,共同充当字段的分析器。
字段的文本被传递给列表中的第一项(solr.StandardTokenizerFactory),从最后一项(solr.EnglishPorterFilterFactory)出现的token是用于索引或查询任何使用”nametext”fieldType字段的词条。

字段值与索引词条

分析器的输出影响给定字段中索引的_词条_(以及在对这些字段进行查询时解析查询时使用的词条),但它对字段的_存储_值没有影响。
例如:分析器可能将”Brown Cow”拆分为两个索引词条”brown”和”cow”,但存储的值仍然是单个字符串:”Brown Cow”

分析阶段

分析发生在两个上下文中。
在索引时,当创建字段时,分析产生的token流被添加到索引中,并定义字段的词条集合(包括位置、大小等)。
在查询时,被搜索的值被分析,产生的词条与存储在字段索引中的那些词条匹配。

在许多情况下,相同的分析应该应用于两个阶段。
当你想要查询精确的字符串匹配时,这是理想的,例如可能不区分大小写。
在其他情况下,你可能希望在索引期间应用与查询时使用的略有不同的分析步骤。

如果你为字段类型提供一个简单的<analyzer>定义,如上面的例子,那么它将用于索引和查询。
如果你希望为每个阶段使用不同的分析器,你可以包含两个用type属性区分的<analyzer>定义。
例如:

使用名称:

1
2
3
4
5
6
7
8
9
10
11
12
<fieldType name="nametext" class="solr.TextField">
<analyzer type="index">
<tokenizer name="standard"/>
<filter name="lowercase"/>
<filter name="keepWord" words="keepwords.txt"/>
<filter name="synonymFilter" synonyms="syns.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer name="standard"/>
<filter name="lowercase"/>
</analyzer>
</fieldType>

使用类名(遗留):

1
2
3
4
5
6
7
8
9
10
11
12
<fieldType name="nametext" class="solr.TextField">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeepWordFilterFactory" words="keepwords.txt"/>
<filter class="solr.SynonymFilterFactory" synonyms="syns.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>

在这个理论例子中,在索引时文本被分词,token被设置为小写,任何没有列在keepwords.txt中的被丢弃,剩下的根据syns.txt文件中的同义词规则映射为替代值。
这本质上从一个受限制的可能值集合构建索引,然后将它们标准化为甚至可能不出现在原始文本中的值。

在查询时,唯一发生的标准化是将查询词条转换为小写。
在索引时发生的过滤和映射步骤不应用于查询词条。
在这个例子中,查询必须非常精确,只使用在索引时存储的标准化词条。

多词扩展的分析

在某些类型的查询中(即前缀、通配符、正则表达式等),用户提供的输入不是用于分析的自然语言。
同义词或停用词过滤等在这些类型的查询中不能以逻辑方式工作。

当Solr需要为导致多词扩展的查询执行分析时,会为过滤器链中的每个工厂调用normalize方法。
在这种上下文中不合理的过滤器的工厂将返回其输入不变。
标准化适用于CharFilters和TokenFilters。

对于大多数用例,这提供了最好的可能行为,但如果你希望对这些类型查询执行的分析有绝对控制权,你可以显式定义一个multiterm分析器来使用,如下例所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<fieldType name="nametext" class="solr.TextField">
<analyzer type="index">
<tokenizer name="standard"/>
<filter name="lowercase"/>
<filter name="keepWord" words="keepwords.txt"/>
<filter name="synonym" synonyms="syns.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer name="standard"/>
<filter name="lowercase"/>
</analyzer>
<!-- 在进行涉及多词扩展的查询时不进行分析 -->
<analyzer type="multiterm">
<tokenizer name="keyword" />
</analyzer>
</fieldType>
© 2025 Solr Community of China All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero