建议器

Solr 中的 SuggestComponent 为用户提供查询词的自动建议。

您可以使用它在您的搜索应用程序中实现强大的自动建议功能。

虽然可以使用拼写检查功能来支持自动建议行为,但 Solr 有一个专用的 SuggestComponent,专为该功能而设计。

此方法利用 Lucene 的 Suggester 实现,并支持 Lucene 中所有可用的查找实现。

此 Suggester 的主要功能是

  • 查找实现的可插拔性

  • 术语字典的可插拔性,使您可以灵活地选择字典实现

  • 分布式支持

在 Solr 的 “techproducts” 示例中找到的 solrconfig.xml 已经配置了 Suggester 实现。有关搜索组件的更多信息,请参阅请求处理程序和搜索组件部分。

“techproducts” 示例 solrconfig.xml 已经配置了一个 suggest 搜索组件和一个 /suggest 请求处理程序。您可以使用它作为您配置的基础,或者从头开始创建,如下文详述。

添加建议搜索组件

第一步是将搜索组件添加到 solrconfig.xml 并告诉它使用 SuggestComponent。以下是一些可以使用的示例代码。

<searchComponent name="suggest" class="solr.SuggestComponent">
  <lst name="suggester">
    <str name="name">mySuggester</str>
    <str name="lookupImpl">FuzzyLookupFactory</str>
    <str name="dictionaryImpl">DocumentDictionaryFactory</str>
    <str name="field">cat</str>
    <str name="weightField">price</str>
    <str name="suggestAnalyzerFieldType">string</str>
    <str name="buildOnStartup">false</str>
  </lst>
</searchComponent>

建议器搜索组件参数

建议器搜索组件接受多个配置参数。

查找实现的选择(lookupImpl,如何在建议字典中找到术语)和字典实现的选择(dictionaryImpl,如何在建议字典中存储术语)将决定所需的一些参数。

以下是不管使用哪种查找或字典实现都可以使用的主要参数。在以下部分中,为每个实现提供了其他参数。

searchComponent 名称

必需

默认:无

整个搜索组件定义的任意名称。

searchComponent 类

必需

默认:无

建议器类。应将其定义为 solr.SuggestComponent

名称

必需

默认:无

此建议器的符号名称。您可以在 URL 参数和 SearchHandler 配置中引用此名称。可以在一个 solrconfig.xml 文件中拥有多个这些。在上面的示例配置中,这是行 <str name="name">mySuggester</str> 中引用的名称。

lookupImpl

可选

默认:JaspellLookupFactory

查找实现。有几种可能的实现,在查找实现部分中描述。

dictionaryImpl

可选

默认值:请参阅描述

要使用的字典实现。有几种可能的实现,在字典实现部分中描述。

如果未设置,则默认字典实现为 HighFrequencyDictionaryFactory。但是,如果使用 sourceLocation,则字典实现将为 FileDictionaryFactory

字段

可选

默认:无

索引中的一个字段,用作建议术语的基础。如果 sourceLocation 为空(表示除 FileDictionaryFactory 之外的任何字典实现),则将使用索引中此字段的术语。

要用作建议的基础,该字段必须存储。您可能希望使用 copyField 规则创建一个由文档中其他字段的术语组成的特殊“建议”字段。

您通常希望对该字段进行最少的分析(不进行词干提取、不使用同义词等),因此一种选择是在您的模式中创建一个仅使用基本分词器或过滤器的字段类型。此处显示了此类字段类型的示例

<fieldType class="solr.TextField" name="textSuggest" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

但是,如果您希望对词条进行更多分析,则不需要此最小化分析。

但是,如果使用 AnalyzingLookupFactory 作为您的 lookupImpl,您可以选择定义用于索引和查询时分析的字段类型规则。

sourceLocation

可选

默认值:请参阅描述

如果使用 FileDictionaryFactory,则为字典文件的路径。如果此值为空,则主索引将用作词条和权重的来源。

storeDir

可选

默认:无

用于存储字典文件的位置。

buildOnCommitbuildOnOptimize

可选

默认值: false

如果为 true,则在软提交后将重建查找数据结构。如果为 false,则仅当 URL 参数 suggest.build=true 请求时才构建查找数据。使用 buildOnCommit 在每次软提交时重建字典,或使用 buildOnOptimize 仅在优化索引时构建字典。

某些查找实现可能需要很长时间才能构建,尤其是在大型索引的情况下。在这种情况下,不建议使用 buildOnCommitbuildOnOptimize,尤其是在软提交频率很高的情况下。相反,应通过手动发出带有 suggest.build=true 的请求来以较低的频率构建建议器。

buildOnStartup

可选

默认值: false

如果为 true,则在 Solr 启动或重新加载核心时将构建查找数据结构。如果未指定此参数,则建议器将检查查找数据结构是否存在于磁盘上,如果未找到则构建它。

将此项设置为 true 可能会导致 Solr 加载(或重新加载)核心的时间更长,因为要构建建议器数据结构,有时这可能需要很长时间。通常首选将其设置为 false,并使用 suggest.build=true 手动构建建议器。

查找实现

lookupImpl 参数定义用于在建议索引中查找词条的算法。有几种可能的实现可供选择,其中一些需要配置其他参数。

AnalyzingLookupFactory

一种查找,首先分析传入的文本并将分析后的形式添加到加权 FST,然后在查找时执行相同的操作。

此实现使用以下附加属性

suggestAnalyzerFieldType

必需

默认:无

用于查询时和构建时词条建议分析的字段类型。

exactMatchFirst

可选

默认值:true

如果为 true,则即使 FST 中的前缀或其他字符串具有更大的权重,也会首先返回精确建议。

preserveSep

可选

默认值:true

如果为 true,则保留标记之间的分隔符。这意味着建议对标记化敏感(例如,棒球与 base ball 不同)。

preservePositionIncrements

可选

默认值: false

如果为 true,则建议器将保留位置增量。这意味着,当 Token 过滤器留下空白(例如,当 StopFilter 匹配停用词时)时,在构建建议器时将尊重该位置。

FuzzyLookupFactory

这是一个建议器,它是 AnalyzingSuggester 的扩展,但本质上是模糊的。相似性通过 Levenshtein 算法测量。

此实现使用以下附加属性

exactMatchFirst

可选

默认值:true

如果为 true,则即使 FST 中的前缀或其他字符串具有更大的权重,也会首先返回精确建议。

preserveSep

可选

默认值:true

如果为 true,则保留标记之间的分隔符。这意味着建议对标记化敏感(例如,“baseball” 与 “base ball” 不同)。

maxSurfaceFormsPerAnalyzedForm

可选

默认值:256

对于单个分析形式,要保留的最大表面形式数。当有太多表面形式时,我们将丢弃权重最低的那些。

maxGraphExpansions

可选

默认值:-1

构建 FST(“索引时”)时,我们将通过 tokenstream 图的每个路径添加为单独的条目。这会对单个建议添加的扩展数量设置上限。

preservePositionIncrements

可选

默认值: false

如果为 true,则建议器将保留位置增量。这意味着,当 Token 过滤器留下空白(例如,当 StopFilter 匹配停用词时)时,在构建建议器时将尊重该位置。

maxEdits

可选

默认值:1

允许的最大字符串编辑次数。Solr 的硬限制为 2

transpositions

可选

默认值:true

如果为 true,则应将转置视为原始编辑操作。

nonFuzzyPrefix

可选

默认值:1

必须与建议匹配的公共非模糊前缀匹配的长度。

minFuzzyLength

可选

默认值:3

允许任何字符串编辑之前的查询的最小长度。

unicodeAware

可选

默认值: false

如果为 true,则 maxEditsminFuzzyLengthtranspositionsnonFuzzyPrefix 参数将以 Unicode 代码点(实际字母)而不是字节来衡量。

AnalyzingInfixLookupFactory

分析输入文本,然后基于与索引文本中任何标记的前缀匹配来建议匹配项。这使用 Lucene 索引作为其字典。

此实现使用以下附加属性。

indexPath

可选

默认值:请参阅描述

当使用 AnalyzingInfixSuggester 时,您可以提供自己的路径,将在该路径中构建索引。默认值为 analyzingInfixSuggesterIndexDir,它将在您的集合的 data/ 目录中创建。

minPrefixChars

可选

默认值:4

使用 PrefixQuery 之前的前导字符的最小数量。短于此的前缀将作为字符 n-gram 索引(增加索引大小,但使查找更快)。

allTermsRequired

可选

默认值:true

如果为 true,则将需要所有词条。

highlight

可选

默认值:true

突出显示建议的词条。

此实现支持上下文过滤

BlendedInfixLookupFactory

AnalyzingInfixSuggester 的扩展,它提供了额外的功能来权衡匹配文档中的前缀匹配。如果命中更接近建议的开头,则得分更高。

此实现使用以下附加属性

blenderType

可选

默认值:position_linear

用于使用第一个匹配词的位置计算权重系数。可用选项包括

  • position_linear:与开头匹配的词条将被赋予更高的分数。

    weightFieldValue * (1 - 0.10*position)

  • position_reciprocal:与开头匹配的词条将被赋予更高的分数。与线性相比,位置远离建议开头的匹配项的得分衰减更快。

    weightFieldValue / (1 + position)

  • position_exponential_reciprocal:与开头匹配的词条将被赋予更高的分数。与倒数相比,位置远离建议开头的匹配项的得分衰减更快。

    weightFieldValue / pow(1 + position,exponent)

    当使用此混合器类型时,可以使用其他参数

    • exponent:控制分数下降的速度。默认值为 2.0

numFactor

可选

默认值:10

用于乘以将从中修剪结果的搜索元素的数量的因子。

indexPath

可选

默认值:请参阅描述

当使用 BlendedInfixSuggester 时,您可以提供自己的路径,将在该路径中构建索引。默认目录名称为 blendedInfixSuggesterIndexDir,它将在您的集合的数据目录中创建。

minPrefixChars

可选

默认值:4

使用 PrefixQuery 之前的前导字符的最小数量。短于此的前缀将作为字符 n-gram 索引,这会增加索引大小,但使查找更快。

此实现支持上下文过滤

FreeTextLookupFactory

它会查看最后一个标记加上用户正在键入的任何最终标记的前缀(如果存在),以预测最可能的下一个标记。还可以指定需要考虑的先前标记的数量。只有当主建议器未能找到任何建议时,才会将此建议器用作后备方案。

此实现使用以下附加属性

suggestFreeTextAnalyzerFieldType

必需

默认:无

用于“查询时”和“构建时”分析建议的字段类型。

ngrams

可选

默认值:2

从中创建字典的单个标记的最大数量。增加此值意味着您希望在提出建议时考虑超过前 2 个标记。

FSTLookupFactory

基于自动机的查找。此实现的构建速度较慢,但提供了最低的内存成本。我们建议使用此实现,除非您需要更复杂的匹配结果,在这种情况下,您应该使用 Jaspell 实现。

此实现使用以下附加属性

exactMatchFirst

可选

默认值:true

如果为 true(默认值),则即使 FST 中的前缀或其他字符串具有更大的权重,也会首先返回精确建议。

weightBuckets

可选

默认:无

建议器在构建其字典时将使用的权重单独存储桶的数量。

TSTLookupFactory

一个简单的基于紧凑三元树的查找。

WFSTLookupFactory

加权自动机表示,它是用于更细粒度排序的 FSTLookup 的替代方案。WFSTLookup 不使用存储桶,而是使用最短路径算法。

请注意,它期望权重为整数。如果缺少权重,则假定为 1.0。当选择 spellcheck.onlyMorePopular=true 时,权重会影响匹配建议的排序:权重被视为“受欢迎程度”得分,权重较高的建议优先于权重较低的建议。

JaspellLookupFactory

一个更复杂的查找,它基于来自 JaSpell 项目的三元树。如果您需要更复杂的匹配结果,请使用此实现。

字典实现

字典实现定义了词条的存储方式。有几个选项,如果需要,可以在单个请求中使用多个字典。

DocumentDictionaryFactory

一个带有来自索引的词条、权重和可选有效负载的字典。

除了通常为建议器和查找实现描述的参数之外,此字典实现还采用以下参数

weightField

可选

默认:无

一个存储的字段或一个数字 DocValue 字段。

payloadField

可选

默认:无

payloadField 应该是一个存储的字段。

contextField

可选

默认:无

用于上下文过滤的字段。请注意,只有某些查找实现支持过滤。

DocumentExpressionDictionaryFactory

此字典实现与 DocumentDictionaryFactory 相同,但允许用户在 weightExpression 标记中指定任意表达式。

除了通常为建议器和查找实现描述的参数之外,此字典实现还采用以下参数

payloadField

可选

默认:无

payloadField 应该是一个存储的字段。

weightExpression

必需

默认:无

用于对建议进行评分的任意表达式。使用的字段必须是数字字段。

contextField

可选

默认:无

用于上下文过滤的字段。请注意,只有某些查找实现支持过滤。

HighFrequencyDictionaryFactory

此字典实现允许添加阈值以修剪掉不常用的词条,以防非常常见的词条淹没其他词条。

除了通常为建议器和查找实现描述的参数之外,此字典实现还采用一个参数

threshold

可选

默认值:0

一个介于 01 之间的值,表示一个词条要被添加到查找字典中,应在其中出现的文档总数的最小分数。

FileDictionaryFactory

此字典实现允许使用包含建议条目的外部文件。也可以使用权重和有效负载。

如果使用字典文件,它应该是一个 UTF-8 编码的纯文本文件。您可以在字典文件中使用单个词条和短语。如果添加权重或有效负载,则应使用 fieldDelimiter 属性定义的定界符(默认为 \t,即制表符表示)将它们与词条分开。如果使用有效负载,则文件中的第一行必须指定有效负载。

除了通常为建议器和查找实现描述的参数之外,此字典实现还采用一个参数

fieldDelimiter

可选

默认值:\t

指定用于分隔条目、权重和有效负载的定界符。默认值是制表符 (\t)。

示例文件
acquire
accidentally    2.0
accommodate 3.0

多个字典

可以在单个 SuggestComponent 定义中包含多个 dictionaryImpl 定义。

为此,只需定义单独的建议器,如本例所示

<searchComponent name="suggest" class="solr.SuggestComponent">
  <lst name="suggester">
    <str name="name">mySuggester</str>
    <str name="lookupImpl">FuzzyLookupFactory</str>
    <str name="dictionaryImpl">DocumentDictionaryFactory</str>
    <str name="field">cat</str>
    <str name="weightField">price</str>
    <str name="suggestAnalyzerFieldType">string</str>
  </lst>
  <lst name="suggester">
    <str name="name">altSuggester</str>
    <str name="dictionaryImpl">DocumentExpressionDictionaryFactory</str>
    <str name="lookupImpl">FuzzyLookupFactory</str>
    <str name="field">product_name</str>
    <str name="weightExpression">((price * 2) + ln(popularity))</str>
    <str name="sortField">weight</str>
    <str name="sortField">price</str>
    <str name="storeDir">suggest_fuzzy_doc_expr_dict</str>
    <str name="suggestAnalyzerFieldType">text_en</str>
  </lst>
</searchComponent>

在查询中使用这些 Suggester 时,您需要在请求中定义多个 suggest.dictionary 参数,这些参数引用搜索组件定义中为每个 Suggester 指定的名称。响应将包括每个 Suggester 的部分中的术语。请参阅下面的示例用法部分,了解示例请求和响应。

添加 Suggest 请求处理器

添加搜索组件后,必须将请求处理器添加到 solrconfig.xml。此请求处理器的工作方式与任何其他请求处理器相同,并允许您配置用于服务建议请求的默认参数。请求处理器定义必须包含先前定义的“suggest”搜索组件。

<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
  <lst name="defaults">
    <str name="suggest">true</str>
    <str name="suggest.count">10</str>
  </lst>
  <arr name="components">
    <str>suggest</str>
  </arr>
</requestHandler>

Suggest 请求处理器参数

以下参数允许您为 Suggest 请求处理器设置默认值

suggest

可选

默认值: false

此参数应始终为 true,因为我们始终希望为此处理器提交的查询运行 Suggester。

suggest.dictionary

必需

默认:无

在搜索组件中配置的字典组件的名称。可以在请求处理器中设置,也可以在查询时作为参数发送。

suggest.q

可选

默认:无

用于建议查找的查询。如果未提供,则使用 q 参数。

suggest.count

可选

默认值:1

指定 Solr 返回的建议数量。

suggest.cfq

可选

默认:无

一个上下文筛选器查询,用于根据上下文字段筛选建议(如果 suggester 支持)。

上下文筛选目前仅受 AnalyzingInfixLookupFactoryBlendedInfixLookupFactory 支持,并且仅在由 Document*Dictionary 支持时才支持。所有其他实现将返回未筛选的匹配项,就好像未请求筛选一样。

suggest.build

可选

默认值: false

如果为 true,它将构建 suggester 索引。这可能仅对初始请求有用;您可能不希望在每个请求上构建字典,尤其是在生产系统中。如果您想保持字典最新,则应为搜索组件使用 buildOnCommitbuildOnOptimize 参数。

suggest.reload

可选

默认值: false

如果为 true,它将重新加载 suggester 索引。

suggest.buildAll

可选

默认值: false

如果为 true,它将构建所有 suggester 索引。

suggest.reloadAll

可选

默认值: false

如果为 true,它将重新加载所有 suggester 索引。

这些属性也可以在查询时被覆盖,或者根本不在请求处理器中设置,而始终在查询时发送。

示例用法

获取带权重的建议

这是使用单个字典和单个 Solr 核心的基本建议。

示例查询

https://127.0.0.1:8983/solr/techproducts/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&suggest.q=elec

在此示例中,我们只是使用 suggest.q 参数请求了字符串 'elec',并请求使用 suggest.build 构建建议字典(但请注意,您可能不希望在每次查询时都构建索引,如果您的文档经常更改,则应改用 buildOnCommitbuildOnOptimize)。

示例响应

{
  "responseHeader": {
    "status": 0,
    "QTime": 35
  },
  "command": "build",
  "suggest": {
    "mySuggester": {
      "elec": {
        "numFound": 3,
        "suggestions": [
          {
            "term": "electronics and computer1",
            "weight": 2199,
            "payload": ""
          },
          {
            "term": "electronics",
            "weight": 649,
            "payload": ""
          },
          {
            "term": "electronics and stuff2",
            "weight": 279,
            "payload": ""
          }
        ]
      }
    }
  }
}

使用多个字典

如果您定义了多个字典,则可以在查询中使用它们。

示例查询

https://127.0.0.1:8983/solr/techproducts/suggest?suggest=true&suggest.dictionary=mySuggester&suggest.dictionary=altSuggester&suggest.q=elec

在此示例中,我们将字符串 'elec' 作为 suggest.q 参数发送,并命名了两个要使用的 suggest.dictionary 定义。

示例响应

{
  "responseHeader": {
    "status": 0,
    "QTime": 3
  },
  "suggest": {
    "mySuggester": {
      "elec": {
        "numFound": 1,
        "suggestions": [
          {
            "term": "electronics and computer1",
            "weight": 100,
            "payload": ""
          }
        ]
      }
    },
    "altSuggester": {
      "elec": {
        "numFound": 1,
        "suggestions": [
          {
            "term": "electronics and computer1",
            "weight": 10,
            "payload": ""
          }
        ]
      }
    }
  }
}

上下文筛选

上下文筛选允许您通过单独的上下文字段(例如类别、部门或任何其他标记)来筛选建议。AnalyzingInfixLookupFactoryBlendedInfixLookupFactory 当前支持此功能,当由 DocumentDictionaryFactory 支持时。

contextField 添加到您的 suggester 配置。此示例将建议名称并允许按类别筛选

solrconfig.xml
<searchComponent name="suggest" class="solr.SuggestComponent">
  <lst name="suggester">
    <str name="name">mySuggester</str>
    <str name="lookupImpl">AnalyzingInfixLookupFactory</str>
    <str name="dictionaryImpl">DocumentDictionaryFactory</str>
    <str name="field">name</str>
    <str name="weightField">price</str>
    <str name="contextField">cat</str>
    <str name="suggestAnalyzerFieldType">string</str>
    <str name="buildOnStartup">false</str>
  </lst>
</searchComponent>

示例上下文筛选建议查询

https://127.0.0.1:8983/solr/techproducts/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&suggest.q=c&suggest.cfq=memory

suggester 将仅返回标记有 'cat=memory' 的产品的建议。