建議器
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
-
選用
預設值:無
儲存字典檔案的位置。
buildOnCommit
和buildOnOptimize
-
選用
預設值:
false
如果為
true
,則在軟提交後會重建查找資料結構。如果為false
,則查找資料只會在 URL 參數suggest.build=true
要求時建立。使用buildOnCommit
在每次軟提交時重建字典,或使用buildOnOptimize
僅在索引最佳化時建立字典。某些查找實作可能需要很長時間來建立,尤其是在大型索引的情況下。在這種情況下,不建議使用
buildOnCommit
或buildOnOptimize
,特別是在軟提交頻率較高時。相反地,請以較低的頻率,透過手動發出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
,則maxEdits
、minFuzzyLength
、transpositions
和nonFuzzyPrefix
參數將以 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
-
選用
預設值:無
權重的個別儲存貯體數量,建議器在建立字典時會使用這些儲存貯體。
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
一個介於
0
和1
之間的值,表示一個詞條要被添加到查找字典中,它應該出現在總文件數中的最小比例。
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 支援。
內容過濾目前僅由
AnalyzingInfixLookupFactory
和BlendedInfixLookupFactory
支援,並且僅在由Document*Dictionary
支援時。所有其他實作將傳回未經篩選的匹配項,就像沒有請求過濾一樣。 suggest.build
-
選用
預設值:
false
如果為
true
,它將建置 suggester 索引。這可能僅對初始請求有用;您可能不希望在每個請求上建置字典,尤其是在生產系統中。如果您想保持字典為最新狀態,您應該使用搜尋元件的buildOnCommit
或buildOnOptimize
參數。 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
建置建議字典(請注意,您可能不希望在每次查詢時都建置索引 - 如果您有經常變更的文件,則應改用 buildOnCommit
或 buildOnOptimize
)。
範例回應
{
"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": ""
}
]
}
}
}
}
內容過濾
內容過濾可讓您依單獨的內容欄位(例如類別、部門或任何其他符記)篩選建議。AnalyzingInfixLookupFactory
和 BlendedInfixLookupFactory
目前支援此功能,當由 DocumentDictionaryFactory
支援時。
將 contextField
新增至您的 suggester 設定。此範例將建議名稱,並允許依類別篩選。
<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」的產品建議。