拼字檢查

拼字檢查元件旨在根據其他類似的詞彙提供內嵌查詢建議。

這些建議的基礎可以是 Solr 中欄位的詞彙、外部建立的文字檔案,或是在其他 Lucene 索引中的欄位。

設定 SpellCheckComponent

在 solrconfig.xml 中定義拼字檢查

第一步是在 solrconfig.xml 中指定詞彙的來源。Solr 中有多種拼字檢查方法,如下所述。

IndexBasedSpellChecker

IndexBasedSpellChecker 使用 Solr 索引作為平行索引的基礎,用於拼字檢查。它需要將一個欄位定義為索引詞彙的基礎;常見的做法是將某些欄位(例如 titlebody 等)的詞彙複製到另一個為拼字檢查建立的欄位。以下是在 solrconfig.xml 中設定 IndexBasedSpellChecker 的範例

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="classname">solr.IndexBasedSpellChecker</str>
    <!-- required parameters -->
    <str name="field">content</str>
    <!-- optional parameters for IndexBasedSpellChecker -->
    <str name="sourceLocation">./folder/with/index/files</str>
    <!-- optional parameters for all spellcheckers -->
    <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 中如何配置它的方法

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="classname">solr.DirectSolrSpellChecker</str>
    <!-- required parameters -->
    <str name="field">name</str>
    <!-- optional parameters for 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>
    <!-- optional parameters for all spellcheckers -->
    <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 會減少可能的建議數量(但是,預設值為 2);該值只能為 1 或 2。minPrefix 定義了詞彙應共享的最小字元數。例如,將此值設定為 1 表示拼寫建議都將以相同的字母開頭。

maxInspections 參數定義了在返回結果之前要檢閱的最大可能比對數;預設值為 5。minQueryLength 定義了在提供建議之前查詢中必須包含的字元數;預設值為 4。maxQueryLength 使拼寫檢查器能夠跳過非常長的查詢詞彙,這可以避免昂貴的操作或例外情況。預設情況下,詞彙長度沒有限制。

首先,拼寫檢查器會透過在索引中查詢來分析傳入的查詢字詞。只有索引中沒有的查詢字詞,或太少見(等於或低於 maxQueryFrequency)的字詞才被視為拼寫錯誤,並用於尋找建議。比 maxQueryFrequency 更頻繁的字詞會不變地繞過拼寫檢查器。在找到每個拼寫錯誤字詞的建議後,會篩選出頻率足夠的建議,並以 thresholdTokenFrequency 作為邊界值。這些參數(maxQueryFrequencythresholdTokenFrequency)可以是以小數值表示的百分比(例如 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>
    <!-- required parameters -->
    <str name="sourceLocation">spellings.txt</str>
    <!-- optional parameters for FileBasedSpellChecker -->
    <str name="fieldType">text_general</str>
    <str name="characterEncoding">UTF-8</str>
    <!-- optional parameters for all spellcheckers -->
    <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 中如何配置它的方法

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="classname">solr.WordBreakSolrSpellChecker</str>
    <!-- required parameters -->
    <str name="field">lowerfilt</str>
    <!-- optional parameters for 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>
    <!-- optional parameters for all spellcheckers -->
    <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

<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 元件接受以下描述的參數。

spellcheck

選用

預設值:false

此參數會為請求開啟 SpellCheck 建議。如果為 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.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 start -e techproducts 範例,此查詢顯示定義使用 spellcheck.q 參數的查詢,並強制校對要求所有輸入詞彙都必須比對的簡單請求的結果。

https://127.0.0.1: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

必要

預設值:無

指定分散式索引組態中的 shards。有關分散式索引的更多資訊,請參閱Solr 叢集類型

shards.qt

必要

預設值:無

指定 Solr 用於向 shards 發出請求的請求處理程式。/select 請求處理程式不需要此參數。

例如

https://127.0.0.1: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,也會要求 shards 提供至少五個建議。收集建議後,它們會依據已設定的距離量測 (預設為 Levenshtein 距離) 和彙總頻率排序。