拼写检查

SpellCheck 组件旨在根据其他类似词条提供内联查询建议。

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

配置 SpellCheckComponent

在 solrconfig.xml 中定义拼写检查

第一步是在 solrconfig.xml 中指定术语的来源。Solr 中有三种拼写检查方法,如下所述。

IndexBasedSpellChecker

IndexBasedSpellChecker 使用 Solr 索引作为用于拼写检查的并行索引的基础。它要求将一个字段定义为索引术语的基础;一种常见做法是将某些字段(例如 titlebody 等)中的术语复制到为拼写检查创建的另一个字段中。以下是使用 IndexBasedSpellChecker 配置 solrconfig.xml 的一个简单示例

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="classname">solr.IndexBasedSpellChecker</str>
    <str name="spellcheckIndexDir">./spellchecker</str>
    <str name="field">content</str>
    <str name="buildOnCommit">true</str>
    <!-- optional elements with defaults
    <str name="distanceMeasure">org.apache.lucene.search.spell.LevenshteinDistance</str>
    <str name="accuracy">0.5</str>
    -->
 </lst>
</searchComponent>

第一个元素定义 searchComponent 以使用 solr.SpellCheckComponentclassname 是 SpellCheckComponent 的特定实现,在本例中为 solr.IndexBasedSpellChecker。定义 classname 是可选的;如果未定义,它将默认为 IndexBasedSpellChecker

spellcheckIndexDir 定义保存拼写检查索引的目录的位置,而 field 定义拼写检查术语的源字段(在架构中定义)。在为拼写检查索引选择字段时,最好避免使用经过大量处理的字段,以获得更准确的结果。如果该字段有许多来自处理同义词和/或词干化的单词变体,则除了更有效的拼写数据外,还将使用这些变体创建词典。

最后,buildOnCommit 定义是否在每次提交时(即每次将新文档添加到索引时)构建拼写检查索引。它是可选的,如果你希望将其设置为 false,则可以省略它。

DirectSolrSpellChecker

DirectSolrSpellChecker 使用 Solr 索引中的术语,而无需像 IndexBasedSpellChecker 那样构建并行索引。此拼写检查器的好处是不必定期构建,这意味着术语始终与索引中的术语保持最新。以下是如何在 solrconfig.xml 中配置此项

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="name">default</str>
    <str name="field">name</str>
    <str name="classname">solr.DirectSolrSpellChecker</str>
    <str name="distanceMeasure">internal</str>
    <float name="accuracy">0.5</float>
    <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>
    <float name="thresholdTokenFrequency">.01</float>
  </lst>
</searchComponent>

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

许多参数与这个拼写检查器应如何查询索引以获取术语建议有关。distanceMeasure 定义在拼写检查查询期间要使用的度量。值“internal”使用默认的 Levenshtein 度量,这是与其他拼写检查器实现一起使用的相同度量。

由于此拼写检查器正在查询主索引,因此您可能希望限制其查询索引的频率,以确保避免与用户查询的任何性能冲突。accuracy 设置定义有效建议的阈值,而 maxEdits 定义允许对该术语进行的更改次数。由于大多数拼写错误只有一个字母之差,因此将其设置为 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

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="classname">solr.FileBasedSpellChecker</str>
    <str name="name">file</str>
    <str name="sourceLocation">spellings.txt</str>
    <str name="characterEncoding">UTF-8</str>
    <str name="spellcheckIndexDir">./spellcheckerFile</str>
    <!-- optional elements with defaults
    <str name="distanceMeasure">org.apache.lucene.search.spell.LevenshteinDistance</str>
    <str name="accuracy">0.5</str>
    -->
 </lst>
</searchComponent>

这里的不同之处在于使用 sourceLocation 来定义术语文件的位置,以及使用 characterEncoding 来定义术语文件编码。

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

WordBreakSolrSpellChecker

WordBreakSolrSpellChecker 通过组合相邻的查询术语和/或将术语拆分为多个单词来提供建议。它是 SpellCheckComponent 增强功能,利用了 Lucene 的 WordBreakSpellChecker。它可以检测因空格放置错误而导致的拼写错误,而无需使用基于分片的词典,并为单词拆分错误提供校对支持,包括用户在同一查询中同时出现单个单词拼写错误和单词拆分错误的情况。它还提供分片支持。

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

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="name">wordbreak</str>
    <str name="classname">solr.WordBreakSolrSpellChecker</str>
    <str name="field">lowerfilt</str>
    <str name="combineWords">true</str>
    <str name="breakWords">true</str>
    <int name="maxChanges">10</int>
  </lst>
</searchComponent>

一些参数与对其他拼写检查器的讨论类似,例如 nameclassnamefield。此拼写检查器的新参数是 combineWords,它定义了是否应在词典搜索中组合单词(默认值为 true);breakWords,它定义了是否应在词典搜索期间拆分单词(默认值为 true);以及 maxChanges,它是一个整数,定义了拼写检查器应根据索引检查校对可能性的次数(默认值为 10)。

拼写检查器可以使用传统检查器(即 DirectSolrSpellChecker)进行配置。结果会合并,校对可以包含来自两个拼写检查器的更正组合。

将其添加到请求处理程序

查询将发送到请求处理程序。如果每个请求都应生成建议,则可以将以下内容添加到正在使用的requestHandler

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

可能的参数之一是使用的spellcheck.dictionary,并且可以定义多个。使用多个词典时,将查询所有指定的词典,并将结果交错排列。校对是通过不同拼写检查器的组合创建的,需要注意的是,在同一校对中不会出现多个重叠的更正。

以下是一个使用多个词典的示例

<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.qq

可选

默认值:无

此参数指定要进行拼写检查的查询。

如果定义了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.queryAnalyzerFieldType

可选

默认值:无

Solr 架构中的字段类型。QueryConverter 使用为提供的字段类型配置的分析器对 q 参数的值进行标记化。

此参数指定的字段类型应执行最少的转换。通常,最好避免使用会积极词干提取或 N-Gram 的类型,例如,因为这些类型的分析可能会导致拼写检查出现问题。

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.<DICT_NAME>.key

可选

默认值:无

为处理给定词典的实现指定键/值对。传递的值只是 key=value(剥离 spellcheck.<DICT_NAME>.)。

例如,给定一个名为 foo 的词典,spellcheck.foo.myKey=myValue 将导致 myKey=myValue 传递给处理词典 foo 的实现。

拼写检查示例

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

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

结果

<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

必需

默认值:无

指定分布式索引配置中的分片。有关分布式索引的更多信息,请参阅 Solr 集群类型

shards.qt

必需

默认值:无

指定 Solr 用于向分片发出请求的请求处理程序。/select 请求处理程序不需要此参数。

例如

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,也会要求分片至少提供 5 个建议。收集建议后,将按配置的距离度量(默认情况下为 Levenstein 距离)对它们进行排序,然后按总频率排序。