建議器

Solr 中的 SuggestComponent 可為使用者提供查詢詞彙的自動建議。

您可以使用此功能在搜尋應用程式中實作強大的自動建議功能。

雖然可以使用拼寫檢查功能來支援自動建議行為,但 Solr 具有專門為此功能設計的SuggestComponent

此方法利用 Lucene 的 Suggester 實作,並支援 Lucene 中可用的所有查閱實作。

此建議器的主要功能是

  • 查閱實作外掛程式

  • 詞彙字典外掛程式,讓您可以彈性選擇字典實作

  • 分散式支援

在 Solr 的「techproducts」範例中找到的 solrconfig.xml 已設定建議器實作。如需搜尋元件的詳細資訊,請參閱請求處理器和搜尋元件一節。

「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

field

選用

預設值:無

索引中要用作建議詞基礎的欄位。如果 sourceLocation 為空(表示任何非 FileDictionaryFactory 的字典實作),則會使用索引中此欄位的詞彙。

為了用作建議的基礎,該欄位必須儲存。您可能想要使用 copyField 規則來建立一個特殊的 'suggest' 欄位,該欄位由文件中其他欄位的詞彙組成。

您通常希望對欄位進行最少的分析(無詞幹還原、無同義詞等),因此一個選項是在您的 schema 中建立一個僅使用基本分詞器或過濾器的欄位類型。此處顯示了這種欄位類型的範例

<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,則會保留符記之間的間隔符。這表示建議對符記化敏感(例如,「baseball」與「base ball」不同)。

preservePositionIncrements

選用

預設值:false

如果為 true,建議器將保留位置增量。這表示當符記過濾器留下間隙時(例如,當 StopFilter 比對到停用詞時),在建立建議器時會尊重位置。

FuzzyLookupFactory

這是一個建議器,它是 AnalyzingSuggester 的延伸,但本質上是模糊的。相似度透過 Levenshtein 演算法測量。

此實作使用以下額外的屬性

exactMatchFirst

選用

預設值:true

如果為 true,則會先傳回完全符合的建議,即使它們是 FST 中的前綴或其他權重較大的字串。

preserveSep

選用

預設值:true

如果為 true,則會保留符記之間的間隔符。這表示建議對符記化敏感(例如,「baseball」與「base ball」不同)。

maxSurfaceFormsPerAnalyzedForm

選用

預設值:256

針對單一分析形式保留的最大表面形式數量。當表面形式太多時,我們會捨棄權重最低的那些。

maxGraphExpansions

選用

預設值:-1

在建立 FST(「索引時」)時,我們會將透過符記串流圖的每個路徑新增為個別項目。這會對單一建議新增的展開數量設定上限。

preservePositionIncrements

選用

預設值:false

如果為 true,建議器將保留位置增量。這表示當符記過濾器留下間隙時(例如,當 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

一個字典,包含從索引中取得的詞條、權重和可選的酬載。

除了Suggester的一般參數和查找實作的參數之外,此字典實作還採用以下參數:

weightField

選用

預設值:無

一個已儲存的欄位或數值DocValue欄位。

payloadField

選用

預設值:無

payloadField 應該是一個已儲存的欄位。

contextField

選用

預設值:無

用於內容過濾的欄位。請注意,只有某些查找實作支援過濾。

DocumentExpressionDictionaryFactory

這個字典實作與 DocumentDictionaryFactory 相同,但允許使用者在 weightExpression 標籤中指定任意表達式。

除了Suggester的一般參數和查找實作的參數之外,此字典實作還採用以下參數:

payloadField

選用

預設值:無

payloadField 應該是一個已儲存的欄位。

weightExpression

必要

預設值:無

用於評分建議的任意表達式。使用的欄位必須是數值欄位。

contextField

選用

預設值:無

用於內容過濾的欄位。請注意,只有某些查找實作支援過濾。

HighFrequencyDictionaryFactory

此字典實作允許新增一個閾值,以刪除不常出現的詞條,在非常常見的詞條可能壓過其他詞條的情況下。

除了Suggester的一般參數和查找實作的參數之外,此字典實作還採用一個參數:

threshold

選用

預設值:0

一個介於 01 之間的值,表示一個詞條要被添加到查找字典中,它應該出現在總文件數中的最小比例。

FileDictionaryFactory

此字典實作允許使用包含建議條目的外部檔案。也可以使用權重和酬載。

如果使用字典檔案,它應該是一個UTF-8編碼的純文字檔案。您可以在字典檔案中使用單一詞條和片語。如果新增權重或酬載,這些應該使用 fieldDelimiter 屬性定義的分隔符號(預設為 \t,即製表符)與詞條分隔。如果使用酬載,檔案中的第一行必須指定一個酬載。

除了Suggester的一般參數和查找實作的參數之外,此字典實作還採用一個參數:

fieldDelimiter

選用

預設值:\t

指定用於分隔條目、權重和酬載的分隔符號。預設值是製表符(\t)。

範例檔案
acquire
accidentally    2.0
accommodate 3.0

多個字典

可以在單個 SuggestComponent 定義中包含多個 dictionaryImpl 定義。

若要執行此操作,只需定義單獨的 suggester,如本範例所示:

<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 的章節中包含詞條。請參閱下面的範例用法章節以取得範例請求和回應。

新增建議請求處理程式

新增搜尋元件後,必須在 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

選用

預設值: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」的產品建議。