Solr查询:拼写检查功能详解

Solr查询:拼写检查功能详解

概述

拼写检查组件旨在基于其他类似术语提供内联查询建议。

这些建议的基础可以是Solr字段中的术语、外部创建的文本文件或其他Lucene索引中的字段。

配置SpellCheckComponent

在solrconfig.xml中定义拼写检查

第一步是在solrconfig.xml中指定术语源。Solr中有许多拼写检查方法,下面讨论。

IndexBasedSpellChecker

IndexBasedSpellChecker使用Solr索引作为用于拼写检查的并行索引的基础。它需要定义字段作为索引术语的基础;常见做法是将某些字段(如titlebody等)的术语复制到为拼写检查创建的另一个字段。

以下是在solrconfig.xml中配置IndexBasedSpellChecker的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
<lst name="spellchecker">
<str name="classname">solr.IndexBasedSpellChecker</str>
<!-- 必需参数 -->
<str name="field">content</str>
<!-- IndexBasedSpellChecker的可选参数 -->
<str name="sourceLocation">./folder/with/index/files</str>
<!-- 所有拼写检查器的可选参数 -->
<str name="spellcheckIndexDir">./spellcheckerDir</str>
<str name="name">default</str>
<str name="fieldType">content_ft</str>
<str name="queryAnalyzerFieldType">text_general</str>
<str name="distanceMeasure">org.apache.lucene.search.spell.LevenshteinDistance</str>
<str name="comparatorClass">score</str>
<float name="accuracy">0.5</float>
<float name="thresholdTokenFrequency">0.0</float>
<str name="buildOnCommit">true</str>
<str name="buildOnOptimize">false</str>
</lst>
</searchComponent>

第一个元素定义searchComponent使用solr.SpellCheckComponentclassname是SpellCheckComponent的具体实现,在这种情况下是solr.IndexBasedSpellChecker。定义classname是可选的;如果未定义,将默认为IndexBasedSpellChecker

spellcheckIndexDir定义保存拼写检查索引的目录位置,而field定义拼写检查术语的源字段(在模式中定义)。选择拼写检查索引字段时,最好避免重度处理的字段以获得更准确的结果。如果字段由于处理同义词和/或词干提取而有许多词变化,字典将除了更有效的拼写数据外还用这些变化创建。

默认情况下,此拼写检查器从Solr索引构建其字典。这可以通过指定sourceLocation来更改——使用静态Lucene索引文件的文件夹而不是Solr索引。

可以为拼写检查器分配描述性标签name——如果搜索组件定义多个拼写检查器,这会很有帮助。这样,拼写检查查询可以识别应咨询的拼写检查器子集(有关更多详细信息,请参阅拼写检查参数)。

field的查询分析器用于标记拼写检查查询。如果需要覆盖该行为,配置fieldType,拼写检查器将使用该字段类型的查询分析器。

queryAnalyzerFieldType是Solr模式中的字段类型,工作方式类似于fieldType参数。关键区别在于,当Solr通过spellcheck.q提供的拼写检查查询进行标记时,使用fieldfieldType;当查询通过q参数提供时,使用queryAnalyzerFieldType

此参数指定的字段类型应进行最少的转换。通常最好避免积极词干提取或NGram的类型,例如,因为这些类型的分析可能会影响拼写检查。

distanceMeasurecomparatorClassaccuracythresholdTokenFrequency等常见配置参数提供对返回的拼写检查建议的控制。

如果未指定distanceMeasure,Solr将使用Levenshtein度量,这也是其他拼写检查器实现的默认度量(除了DirectSolrSpellChecker)。

comparatorClass配置为”score”时,距离较低(即相似性较高)分数的建议被认为更相关。替代值是”freq”——这优先考虑具有更高文档频率的建议。

accuracy设置定义有效建议的阈值,thresholdTokenFrequency设置允许跳过在索引中文档频率较低的建议。

最后,buildOnCommitbuildOnOptimize定义是否在每次提交时(即每次向索引添加新文档时)或在每次优化请求时构建拼写检查索引。两者都是可选的,如果您宁愿将其值设置为false,可以省略。

DirectSolrSpellChecker

DirectSolrSpellChecker使用来自Solr索引的术语,而不像IndexBasedSpellChecker那样构建并行索引。此拼写检查器的好处是不必定期构建,这意味着术语始终与索引中的术语保持最新。

以下是在solrconfig.xml中的配置方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
<lst name="spellchecker">
<str name="classname">solr.DirectSolrSpellChecker</str>
<!-- 必需参数 -->
<str name="field">name</str>
<!-- DirectSolrSpellChecker的可选参数 -->
<int name="maxEdits">2</int>
<int name="minPrefix">1</int>
<int name="maxInspections">5</int>
<int name="minQueryLength">4</int>
<int name="maxQueryLength">40</int>
<float name="maxQueryFrequency">0.01</float>
<!-- 所有拼写检查器的可选参数 -->
<str name="name">default</str>
<str name="fieldType">name</str>
<str name="queryAnalyzerFieldType">text_general</str>
<str name="distanceMeasure">internal</str>
<str name="comparatorClass">score</str>
<float name="accuracy">0.5</float>
<float name="thresholdTokenFrequency">0.0</float>
</lst>
</searchComponent>

选择此拼写检查器要查询的field时,您需要一个对其执行相对较少分析的字段(特别是词干提取等分析)。请注意,您需要指定用于建议的字段,因此像IndexBasedSpellChecker一样,您可能希望将数据从titlebody等字段复制到专门用于提供拼写建议的字段。

许多参数与此拼写检查器应如何查询索引以获取术语建议有关。distanceMeasure定义在拼写检查查询期间使用的度量——此拼写检查器的默认值是”internal”,对应于Damerau-Levenshtein度量。

因为此拼写检查器查询主索引,您可能希望限制其查询索引的频率,以确保避免与用户查询的任何性能冲突。accuracy设置定义有效建议的阈值,而maxEdits定义允许对术语的更改数量。由于大多数拼写错误只偏离1个字母,将其设置为1将减少可能建议的数量(但默认值是2);该值只能是1或2。minPrefix定义术语应共享的最小字符数。将其设置为1意味着拼写建议都将以相同字母开头,例如。

maxInspections参数定义在返回结果之前要检查的可能匹配的最大数量;默认为5。minQueryLength定义在提供建议之前查询中必须有多少字符;默认为4。maxQueryLength使拼写检查器能够跳过非常长的查询术语,这可以避免昂贵的操作或异常。默认情况下对术语长度没有限制。

首先,拼写检查器通过在索引中查找传入查询词来分析它们。只有索引中不存在或太稀有(等于或低于maxQueryFrequency)的查询词被认为是拼写错误并用于查找建议。比maxQueryFrequency更频繁的词会绕过拼写检查器不变。找到每个拼写错误词的建议后,它们会根据thresholdTokenFrequency作为边界值进行足够频率过滤。这些参数(maxQueryFrequencythresholdTokenFrequency)可以是表示为1以下小数值的百分比(如0.011%)或绝对值(如4)。

注意:当maxQueryFrequency指定为百分比时,它在每个分片上独立评估(相对于该分片的maxDoc)以确定是否应被视为拼写错误。如果术语分布在分片之间不均匀,某些不频繁术语可能被认为是正确拼写的,并且在预期时不生成建议。

FileBasedSpellChecker

FileBasedSpellChecker使用外部文件作为拼写字典。如果使用Solr作为拼写服务器,或如果拼写建议不需要基于索引中的实际术语,这可能很有用。

solrconfig.xml中,您将这样定义searchComponent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
<lst name="spellchecker">
<str name="classname">solr.FileBasedSpellChecker</str>
<!-- 必需参数 -->
<str name="sourceLocation">spellings.txt</str>
<!-- FileBasedSpellChecker的可选参数 -->
<str name="fieldType">text_general</str>
<str name="characterEncoding">UTF-8</str>
<!-- 所有拼写检查器的可选参数 -->
<str name="spellcheckIndexDir">./spellcheckerDir</str>
<str name="name">file</str>
<str name="queryAnalyzerFieldType">text_general</str>
<str name="distanceMeasure">org.apache.lucene.search.spell.LevenshteinDistance</str>
<str name="comparatorClass">score</str>
<float name="accuracy">0.5</float>
<float name="thresholdTokenFrequency">0.0</float>
<bool name="buildOnCommit">false</bool>
<bool name="buildOnOptimize">false</bool>
</lst>
</searchComponent>

配置与IndexBasedSpellChecker非常相似,这里的区别是使用sourceLocation定义术语文件的位置,使用characterEncoding定义术语文件的编码。

如果指定了fieldType参数并与Solr模式中的类型匹配,Solr将通过首先使用fieldType索引分析器标记外部文件中的每行来构建拼写检查索引,然后将每个标记添加到索引。

如果没有,Solr将外部文件中的每行视为单个标记,并按原样将它们添加到拼写检查索引。

提示:在前面的示例中,使用name来命名拼写检查器的这个特定定义。多个定义可以在单个solrconfig.xml中共存,name有助于区分它们。如果只定义一个拼写检查器,则不需要名称。

WordBreakSolrSpellChecker

WordBreakSolrSpellChecker通过组合相邻查询术语和/或将术语分解为多个词来提供建议。它是SpellCheckComponent的增强,利用Lucene的WordBreakSpellChecker。它可以检测由于错位空白而导致的拼写错误,而无需使用基于shingle的字典,并为词分割错误提供整理支持,包括用户在同一查询中混合单词拼写错误和词分割错误的情况。它还提供分片支持。

以下是在solrconfig.xml中的配置方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
<lst name="spellchecker">
<str name="classname">solr.WordBreakSolrSpellChecker</str>
<!-- 必需参数 -->
<str name="field">lowerfilt</str>
<!-- WordBreakSpellChecker的可选参数 -->
<str name="combineWords">true</str>
<str name="breakWords">true</str>
<str name="breakSuggestionTieBreaker">max_freq</str>
<int name="maxChanges">1</int>
<int name="maxCombinedLength">20</int>
<int name="minBreakLength">1</int>
<int name="maxEvaluations">1000</int>
<int name="minSuggestionFreq">1</int>
<!-- 所有拼写检查器的可选参数 -->
<str name="name">wordbreak</str>
<str name="fieldType">lowerfilt_ft</str>
<str name="queryAnalyzerFieldType">text_general</str>
</lst>
</searchComponent>

一些参数应该从其他拼写检查器的讨论中熟悉,如nameclassnamefield。此拼写检查器的新参数是combineWords,定义是否应在字典搜索中组合词(默认为true);和breakWords,定义是否应在字典搜索期间分解词(默认为true)。

maxChanges是一个整数,定义拼写检查器应检查整理可能性对索引的次数。

maxCombinedLength允许跳过太长的建议。类似地,minBreakLength指示拼写检查器不要将词分解为太短的部分。

maxEvaluations定义要评估的词组合的最大数量——较高的值可能改善结果质量,而较低的值可能改善性能。

minSuggestionFreq设置术语必须具有的最小频率才能作为建议的一部分包含。

最后,breakSuggestionTieBreaker设置(”max_freq”或”sum_freq”)指示Solr按词分解数排序建议,然后分别按所有组件术语频率的最大值或总和排序。

拼写检查器可以与传统检查器(即DirectSolrSpellChecker)一起配置。结果被组合,整理可能包含来自两个拼写检查器的修正混合。

添加到请求处理器

查询将发送到请求处理器。如果每个请求都应生成建议,那么您将向正在使用的requestHandler添加以下内容:

1
<str name="spellcheck">true</str>

可能的参数之一是要使用的spellcheck.dictionary,可以定义多个。使用多个字典时,咨询所有指定的字典并交错结果。使用来自不同拼写检查器的组合创建整理,注意多个重叠纠正不会出现在同一整理中。

以下是多个字典的示例:

1
2
3
4
5
6
7
8
9
10
<requestHandler name="spellCheckWithWordbreak" class="org.apache.solr.handler.component.SearchHandler">
<lst name="defaults">
<str name="spellcheck.dictionary">default</str>
<str name="spellcheck.dictionary">wordbreak</str>
<str name="spellcheck.count">20</str>
</lst>
<arr name="last-components">
<str>spellcheck</str>
</arr>
</requestHandler>

拼写检查参数

拼写检查组件接受以下描述的参数。

spellcheck

  • 可选,默认:false
  • 此参数为请求启用拼写检查建议。如果为true,则将生成拼写建议。如果需要拼写检查,这是必需的

spellcheck.q或q

  • 可选,默认:无
  • 此参数指定要拼写检查的查询
  • 如果定义了spellcheck.q,则使用它;否则使用原始输入查询。spellcheck.q参数旨在是原始查询,减去任何额外标记,如字段名称、提升等
  • 如果指定了q参数,则使用SpellingQueryConverter类将其解析为标记;否则使用WhitespaceTokenizer
  • 选择使用哪一个取决于应用程序。基本上,如果您在应用程序中有拼写”就绪”版本,那么使用spellcheck.q可能更好。否则,如果您只想让Solr完成工作,请使用q参数

注意SpellingQueryConverter类不能正确处理非ASCII字符。在这种情况下,您必须使用spellcheck.q,或实现自己的QueryConverter。

spellcheck.build

  • 可选,默认:false
  • 如果设置为true,此参数创建用于拼写检查的字典。在典型的搜索应用程序中,您需要在使用拼写检查之前构建字典。但是,并不总是需要首先构建字典。例如,您可以配置拼写检查器使用已存在的字典
  • 字典需要一些时间来构建,所以此参数不应与每个请求一起发送

spellcheck.reload

  • 可选,默认:false
  • 如果设置为true,此参数重新加载拼写检查器。结果取决于SolrSpellChecker.reload()的实现。在典型实现中,重新加载拼写检查器意味着重新加载字典

spellcheck.count

  • 可选,默认:见描述
  • 此参数指定拼写检查器应为术语返回的最大建议数。如果未设置此参数,值默认为1。如果设置了参数但未分配数字,值默认为5。如果参数设置为正整数,该数字成为拼写检查器返回的最大建议数

spellcheck.onlyMorePopular

  • 可选,默认:false
  • 如果为true,Solr将返回比现有查询产生更多命中的建议。请注意,即使给定查询术语存在于索引中并被认为是”正确的”,这也会返回更受欢迎的建议

spellcheck.maxResultsForSuggest

  • 可选,默认:无
  • 例如,如果设置为5且用户查询返回5个或更少结果,拼写检查器将报告”correctlySpelled=false”并提供建议(如果请求,还有整理)。将此设置大于零对于为返回少量命中的查询创建”您是否意思是?”建议很有用

spellcheck.alternativeTermCount

  • 可选,默认:无
  • 定义为索引和/或字典中存在的每个查询术语返回的建议数。大概用户希望对docFrequency>0的词有更少的建议。此外,设置此值启用上下文敏感的拼写建议

spellcheck.extendedResults

  • 可选,默认:false
  • 如果为true,此参数使Solr返回关于拼写检查结果的附加信息,例如索引中每个原始术语的频率(origFreq)以及索引中每个建议的频率(frequency)。请注意,此结果格式与非扩展格式不同,因为词的返回建议实际上是列表数组,其中每个列表保存建议的术语及其频率

spellcheck.collate

  • 可选,默认:false
  • 如果为true,此参数指示Solr为每个标记采用最佳建议(如果存在)并从建议构造新查询
  • 例如,如果输入查询是”jawa class lording”,”jawa”的最佳建议是”java”,”lording”是”loading”,那么结果整理将是”java class loading”
  • spellcheck.collate参数只返回即使重新查询时应用原始fq参数也保证产生命中的整理。这在每个查询有多个纠正时特别有用
  • 注意:这只返回要使用的查询。它不实际运行建议的查询

spellcheck.maxCollations

  • 可选,默认:1
  • 返回的最大整理数。如果spellcheck.collate为false,则忽略此参数

spellcheck.maxCollationTries

  • 可选,默认:0
  • 此参数指定Solr在放弃之前尝试的整理可能性数。较低的值确保更好的性能。较高的值可能需要找到可以返回结果的整理。默认值0等价于不检查整理。如果spellcheck.collate为false,则忽略此参数

spellcheck.maxCollationEvaluations

  • 可选,默认:10000
  • 此参数指定在决定要对索引测试哪些整理候选者之前要排序和评估的词纠正组合的最大数量。这是用户输入具有许多拼写错误词的查询时的性能安全网

spellcheck.collateExtendedResults

  • 可选,默认:false
  • 如果为true,此参数返回详细描述Solr找到的整理的扩展响应格式。如果spellcheck.collate为false,则忽略此项

spellcheck.collateMaxCollectDocs

  • 可选,默认:0
  • 此参数指定测试潜在整理对索引时应收集的最大文档数。值0表示应收集所有文档,产生精确的命中计数。否则,提供估计作为性能优化,在不需要精确命中计数的情况下——指定的值越高,估计越精确
  • spellcheck.collateExtendedResultsfalse时,始终使用优化,就像指定了1一样

spellcheck.collateParam.*前缀

  • 可选,默认:无
  • 此参数前缀可用于指定您希望拼写检查器在内部验证整理查询时使用的任何附加参数。例如,即使您的常规搜索结果允许通过q.op=ORmm=20%等参数松散匹配一个或多个查询术语,您可以指定覆盖参数,如spellcheck.collateParam.q.op=AND&spellcheck.collateParam.mm=100%,要求只能返回由在至少一个文档中都找到的词组成的整理

spellcheck.dictionary

  • 可选,默认:default
  • 此参数使Solr使用参数参数中命名的字典。此参数可用于在每个请求基础上调用特定的拼写检查器

spellcheck.accuracy

  • 可选,默认:见描述
  • 指定拼写检查实现使用的精度值来决定结果是否有价值。值是0到1之间的浮点数。默认为Float.MIN_VALUE

spellcheck..key

  • 可选,默认:无
  • 为处理给定字典的实现指定键/值对。传递的值只是key=valuespellcheck.<DICT_NAME>.被剥离)
  • 例如,给定名为foo的字典,spellcheck.foo.myKey=myValue将导致myKey=myValue传递给处理字典foo的实现

拼写检查示例

使用Solr的bin/solr start -e techproducts示例,此查询显示使用spellcheck.q参数定义查询并强制整理要求所有输入术语必须匹配的简单请求结果:

1
http://localhost:8983/solr/techproducts/spell?df=text&spellcheck.q=delll+ultra+sharp&spellcheck=true&spellcheck.collateParam.q.op=AND&wt=xml

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<lst name="spellcheck">
<lst name="suggestions">
<lst name="delll">
<int name="numFound">1</int>
<int name="startOffset">0</int>
<int name="endOffset">5</int>
<int name="origFreq">0</int>
<arr name="suggestion">
<lst>
<str name="word">dell</str>
<int name="freq">1</int>
</lst>
</arr>
</lst>
<lst name="ultra sharp">
<int name="numFound">1</int>
<int name="startOffset">6</int>
<int name="endOffset">17</int>
<int name="origFreq">0</int>
<arr name="suggestion">
<lst>
<str name="word">ultrasharp</str>
<int name="freq">1</int>
</lst>
</arr>
</lst>
</lst>
<bool name="correctlySpelled">false</bool>
<lst name="collations">
<lst name="collation">
<str name="collationQuery">dell ultrasharp</str>
<int name="hits">1</int>
<lst name="misspellingsAndCorrections">
<str name="delll">dell</str>
<str name="ultra sharp">ultrasharp</str>
</lst>
</lst>
</lst>
</lst>

分布式拼写检查

SpellCheckComponent还支持分布式索引上的拼写检查。如果您在除”/select”之外的请求处理器上使用SpellCheckComponent,必须提供以下两个参数:

shards

  • 必需,默认:无
  • 指定分布式索引配置中的分片。有关分布式索引的更多信息,请参阅集群类型

shards.qt

  • 必需,默认:无
  • 指定Solr用于分片请求的请求处理器。/select请求处理器不需要此参数

例如:

1
http://localhost:8983/solr/techproducts/spell?spellcheck=true&spellcheck.build=true&spellcheck.q=toyata&shards.qt=/spell&shards=solr-shard1:8983/solr/techproducts,solr-shard2:8983/solr/techproducts

在分布式请求到SpellCheckComponent的情况下,即使spellcheck.count参数值小于5,也会向分片请求至少五个建议。一旦收集建议,它们按配置的距离度量(默认为Levenshtein距离)然后按聚合频率排序。


本文档翻译自Apache Solr官方参考指南,旨在为中文用户提供完整的拼写检查功能使用指南。

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