Solr:suggest組件使用大全

2018-11-28 17:31 更新

Suggester

Solr 中的 SuggestComponent 為用戶提供查詢 term 的自動建議。

您可以使用此功能在搜索應用程序中實現強大的自動建議功能。

盡管可以使用拼寫檢查功能為自動建議行為提供支持,但 Solr 為此功能專門設計了一個 SuggestComponent。

這種方法利用了 Lucene 的 Suggester 實現,并支持 lucene 中所有可用的查找實現。

這個 Suggester 的主要特點是:

  • 查找實現可插入性
  • term 字典可插入性,使您可以靈活地選擇詞典實現
  • 分布式支持

在 Solr 的 "techproducts" 示例中找到的 solrconfig.xml 已經配置了一個 Suggester 實現。有關搜索組件的更多信息,請參閱 SolrConfig 中的 RequestHandlers 和SearchComponents 部分。

該 techproducts 示例 solrconfig.xml 有一個 suggest 搜索組件和一個已經配置的 /suggest 請求處理程序。您可以將其用作您的配置的基礎,或者從頭開始創(chuàng)建它,如下所述。

添加建議搜索組件

第一步是將搜索組件添加到 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,在建議字典中如何找到 term)和字典實現(dictionaryImpl,term 如何存儲在建議字典中)將決定所需的一些參數。

下面是無論使用什么查找或詞典實現,都可以使用的主要參數。在下面的部分中提供了每個實現的附加參數。

  • searchComponent name 參數

    搜索組件的任意名稱。

  • name 參數

    這個建議的象征性名稱。您可以在 URL 參數和 SearchHandler 配置中引用此名稱。一個solrconfig.xml文件中可能有多個這樣的字符。

  • lookupImpl 參數

    查找實現。有幾種可能的實現,在下面的查找實現一節(jié)中描述。如果沒有設置,默認查找是JaspellLookupFactory

  • dictionaryImpl 參數

    要使用的字典實現。有幾種可能的實現,在“ 字典實現 ”一節(jié)中有描述。

    如果沒有設置,默認的字典實現是HighFrequencyDictionaryFactory。但是,如果使用 sourceLocation,字典的實現將會是FileDictionaryFactory

  • field 參數

    從索引中使用的字段作為建議 term 的基礎。如果sourceLocation為空(表示除了 FileDictionaryFactory 以外的任何字典實現),則將使用來自索引中的該字段的 term。

    作為建議的依據,必須存儲該字段。您可能希望使用 copyField 規(guī)則來創(chuàng)建由文檔中其他字段的 term 組成的特殊“建議”字段。無論如何,您很可能只需要對該字段進行最少量的分析,因此另外一個選擇是在架構中創(chuàng)建一個只使用基本標記或過濾器的字段類型。這里顯示了這種字段類型的一個選項:

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

    但是,如果您想要根據 term 進行更多的分析,則不需要進行這種最低限度的分析。但是,如果使用AnalyzingLookupFactory作為 lookupImpl,則可以選擇定義用于索引和查詢時間分析的字段類型規(guī)則。

  • sourceLocation 參數

    字典文件的路徑,如果使用FileDictionaryFactory。如果這個值是空的,那么主索引將被用作 term 和權重的來源。

  • storeDir 參數

    存儲字典文件的位置。

  • buildOnCommit 和 buildOnOptimize 參數

    如果true,則將在 soft-commit 后重建查找數據結構。如果為false默認情況下,查詢數據將僅在 URL 參數suggest.build=true請求時才被構建。使用buildOnCommit可以用每個 soft-commit 來重建字典,或buildOnOptimize僅在索引被優(yōu)化時才建立字典。

    一些查找實現可能需要很長時間才能構建,特別是對于大型索引。在這種情況下,不建議使用buildOnCommitbuildOnOptimize特別是使用高頻率的 softCommits 。建議使用suggest.build=true手動發(fā)出請求,以較低的頻率構建建議。

  • buildOnStartup 參數

    如果true,那么當 Solr 啟動或內核被重新加載時,查找數據結構將被建立。如果未指定此參數,則建議程序將檢查查找數據結構是否存在于磁盤上,如果未找到,則進行構建。

    如果將其設置為true可能會導致核心花費時間較長(或重新加載),因為建議數據結構需要建立,有時可能需要很長時間。通常首選將此設置設置為false默認設置,而使用suggest.build=true發(fā)出請求來手動構建建議。

查找實現(Lookup Implementations)

該 lookupImpl 參數定義用于在建議索引中查找 term 的算法。有幾種可能的實現可供選擇,有些需要額外的參數進行配置:

AnalyzingLookupFactory

首先分析傳入的文本并將分析后的表格添加到加權的 FST,然后在查找時執(zhí)行相同的操作。

該實現使用以下附加屬性:

  • suggestAnalyzerFieldType 屬性

    用于查詢時間和構建時期建議分析的字段類型。

  • exactMatchFirst 屬性

    如果為true首先返回默認的確切建議,即使它們是前綴或 FST 中有較大權重的其他字符串。

  • preserveSep 屬性

    如果true(默認),那么令牌之間的分隔符被保留。這意味著建議對標記化非常敏感(例如,baseball 與 base ball 不同)。

  • preservePositionIncrements 屬性

    如果true,建議將保留位置增量。這意味著,在構建建議時,會保留標記過濾器(例如,當 StopFilter 匹配停用詞時)留下空隙的位置。默認是false。

FuzzyLookupFactory

這是一個 suggester,它是 AnalyzingSuggester 的延伸,但本質上是模糊的。相似性由 Levenshtein 算法測量。

它的實現使用以下附加屬性:

  • exactMatchFirst 屬性

    如果true(默認),則首先返回確切建議,即使它們是前綴或 FST 中權重較大的其他字符串。

  • preserveSep 屬性

    如果true(默認),那么令牌之間的分隔符被保留。這意味著建議對標記化非常敏感(例如,baseball 與 base ball 不同)。

  • maxSurfaceFormsPerAnalyzedForm 屬性

    為單個分析表單保留的最大表面形式數量。當表面形式太多時,我們丟棄最低的權重。

  • maxGraphExpansions 屬性

    在構建 FST(“索引時間”)時,我們將每個通過令牌流圖的路徑作為單獨的條目添加。這就為一個建議添加了多少擴展的上限。默認是-1這意味著沒有限制。

  • preservePositionIncrements 屬性

    如果true,建議將保留位置增量。這意味著,在構建建議時,會保留標記過濾器(例如,當 StopFilter 匹配停用詞時)留下空隙的位置。默認是false。

  • maxEdits 屬性

    允許的字符串編輯的最大數量。系統的硬性限制是2。默認是1。

  • transpositions 屬性

    如果true默認,則默認的對換應視為原始編輯操作。

  • nonFuzzyPrefix 屬性

    必須匹配建議的通用非模糊前綴匹配的長度。默認是1。

  • minFuzzyLength 屬性

    在任何字符串編輯之前,查詢的最小長度將被允許。默認是3

  • unicodeAware 屬性

    如果true,則maxEdits、minFuzzyLengthtranspositionsnonFuzzyPrefix參數將在 Unicode 代碼點(實際字母),而不是字節(jié)來測量。默認是false。

AnalyzingInfixLookupFactory

分析輸入文本,然后根據索引文本中的任何標記的前綴匹配建議匹配。這為它的字典使用 Lucene 索引。

它的實現使用以下附加屬性。

  • indexPath 屬性

    使用AnalyzingInfixSuggester時,您可以提供自己的路徑,索引將在其中生成。默認值是analyzingInfixSuggesterIndexDir,并將在您的集合的data/目錄中創(chuàng)建。

  • minPrefixChars 屬性

    使用 PrefixQuery 之前的最小字符數(默認值是4)。比這更短的前綴被索引為字符 ngrams(增加索引大小,但查找速度更快)。

  • allTermsRequired 屬性

    多個 term 的布爾選項。默認是true,所有的 term 將是必需的。

  • highlight 屬性

    突出顯示 term。默認是true。

這個實現支持上下文過濾。

BlendedInfixLookupFactory

AnalyzingInfixSuggester 的擴展,它為匹配的文檔中的權重前綴匹配提供附加功能。您可以將其分數提高,如果命中是接近開始的建議,反之亦然。

該實現使用以下附加屬性:

  • blenderType 屬性

    用于使用第一個匹配詞的位置計算權重系數。可以是以下之一:

    • position_linear

      weightFieldValue*(1 - 0.10*position):匹配開始將獲得更高的分數。這是默認的。

    • position_reciprocal

      weightFieldValue/(1+position):匹配結束將獲得更高的分數。

      exponent:position_reciprocal blenderType 的可選配置變量,用于控制分數增加或減少的速度。默認2.0。

  • numFactor 屬性

    要將結果修剪的搜索元素數乘以的系數。默認值為 10。

  • indexPath 屬性

    使用BlendedInfixSuggester時,您可以提供自己的路徑,索引將在其中生成。默認的目錄名稱是blendedInfixSuggesterIndexDir,將在您的集合數據目錄中創(chuàng)建。

  • minPrefixChars 屬性

    使用 PrefixQuery 之前的最小字符數(默認值是4)。比這更短的前綴被索引為字符 ngrams(增加索引大小,但查找速度更快)。

這個實現支持上下文過濾

FreeTextLookupFactory

它會查看最后一個標記以及用戶輸入的任何最終標記的前綴(如果存在),以預測最有可能的下一個標記。還可以指定需要考慮的以前標記的數目。當主要建議未能找到任何建議時,此suggester 只能用作后備。

該實現使用以下附加屬性:

  • suggestFreeTextAnalyzerFieldType 

    分析器用于“查詢時間”和“建立時間”來分析建議。該參數是必需的。

  • ngrams

    最大數量的標記數,其中超出的單個將被作為字典。默認值是2。如果增加這個數字,意味著在提出建議時,要比以前的兩個標記考慮的要多。

FSTLookupFactory

基于自動機的查找。此實現的生成速度較慢,但是提供了最低的內存成本。除非您需要更復雜的匹配結果,否則我們推薦使用此實現,在這種情況下,您應該使用 Jaspell 實現。

該實現使用以下附加屬性:

  • exactMatchFirst

    如果true(默認的)首先返回確切建議,即使它們是前綴或 FST 中權重較大的其他字符串。

  • weightBuckets

    在建立詞典時,建議將使用的權重的單獨的 bucket 的數量。

TSTLookupFactory

一種簡單的基于三元線索的查找。

WFSTLookupFactory

一個加權自動機表示,這是一個替代 FSTLookup 的更細致的排序。WFSTLookup不使用 bucket,而是使用最短路徑算法。

請注意,它期望權重是整數。如果重量不足,則認為是1.0。權重在 spellcheck.onlyMorePopular=true 時影響匹配建議的排序:權重被視為“受歡迎程度”分數,較高的權重優(yōu)先于權重較低的建議。

JaspellLookupFactory

基于 JaSpell 項目的三元樹查找更復雜的查找。如果您需要更復雜的匹配結果,請使用此實現。

字典實現

字典實現定義 term 的存儲方式。有幾個選項,如果需要,可以在單個請求中使用多個字典。

DocumentDictionaryFactory

包含 term、權重和從索引中提取的可選有效負載的字典。

除了通常為 Suggester 描述的參數以及查找實現之外,該字典實現還采用以下參數:

  • weightField

    存儲的字段或數字 DocValue 字段。該參數是可選的。

  • payloadField

    payloadField應存儲的字段。該參數是可選的。

  • contextField

    用于上下文過濾的字段。請注意,只有一些查找實現支持過濾。

DocumentExpressionDictionaryFactory

此字典實現與 DocumentDictionaryFactory 相同,但允許用戶將任意表達式指定到 weightExpression 標記中。
除了通常為 Suggester 描述的參數和查找實現之外,此字典實現還采用以下參數:

  • payloadField

    payloadField應存儲的字段。該參數是可選的。

  • weightExpression

    用于對建議進行評分的任意表達式。使用的字段必須是數字字段。此參數是必需的。

  • contextField

    用于上下文過濾的字段。請注意,只有一些查找實現支持過濾。

HighFrequencyDictionaryFactory

這個字典的實現允許在非常常見的 term 可能壓倒其他 term 的情況下,添加閾值以減少不常用的 term。

除了通常為 Suggester 描述的參數和查找實現之外,此字典實現還需要一個參數:

  • threshold

    介于0和1之間的值,表示為了添加到查閱字典而應出現的文檔總數的最小部分。

FileDictionaryFactory

這個字典實現允許使用包含建議條目的外部文件。權重和有效載荷也可以使用。

如果使用字典文件,它應該是 UTF-8 編碼的純文本文件。您可以在詞典文件中同時使用單個 term 和短語。如果添加權重或有效負載,則應使用與 fieldDelimiter 屬性一起定義的分隔符(默認值為“\ t”,即制表符)將其與 term 分開。如果使用有效載荷,則文件中的第一行必須指定有效載荷。

除了通常為 Suggester 描述的參數和查找實現之外,此字典實現還需要一個參數:

  • fieldDelimiter

    指定分隔條目、權重和有效載荷的分隔符。默認是tab(\t)。

    示例文件:
    acquire
    accidentally    2.0
    accommodate 3.0

多個詞典

可以在單個 SuggestComponent 定義中包含多個 dictionaryImpl 定義。
為此,只需定義單獨的 suggesters,如以下示例所示:

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

在查詢中使用這些 Suggesters 時,您可以在請求中定義多個 suggest.dictionary 參數,引用在搜索組件定義中為每個 Suggester 指定的名稱。響應將包括每個提示的章節(jié)中的 term。有關示例請求和響應,請參見下面的示例使用部分。

添加 Suggest 請求處理程序

添加搜索組件后,必須添加一個請求處理程序到 solrconfig.xml 中。這個請求處理程序與任何其他請求處理程序一樣工作,并允許您為服務建議請求配置默認參數。請求處理程序定義必須包含之前定義的“建議”搜索組件。

<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=true

    這個參數應該總是true,因為我們總是想運行提交給這個處理程序的查詢的 Suggester。

  • suggest.dictionary

    在搜索組件中配置的字典組件的名稱。這是一個強制參數。它可以在請求處理程序中設置,或者在查詢時作為參數發(fā)送。

  • suggest.q

    用于建議查找的查詢。

  • suggest.count

    指定 Solr 返回的建議數量。

  • suggest.cfq

    上下文過濾器查詢,用于根據上下文字段篩選建議 (如果 suggester 支持)。

  • suggest.build

    如果true,它會建立建議索引。這可能只對最初的請求有用;您可能不想在每個請求上建立字典,特別是在生產系統中。如果您想保持您的字典是最新的,您應該使用buildOnCommitbuildOnOptimize參數搜索組件。

  • suggest.reload

    如果true它將重新加載建議索引。

  • suggest.buildAll

    如果true,它會建立所有的建議索引。

  • suggest.reloadAll

    如果true它將重新加載所有的建議索引。

這些屬性也可以在查詢時被覆蓋,或者根本不在請求處理器中設置,并且總是在查詢時發(fā)送。

上下文過濾:上下文過濾(suggest.cfq)目前只支持AnalyzingInfixLookupFactoryBlendedInfixLookupFactory,并且只有在Document*Dictionary支持的情況下。所有其他的實現將返回未經過濾的匹配,就好像沒有請求過濾一樣。

使用示例

通過權重獲取建議

這是使用單個字典和單個 Solr 核心的基本建議。

示例查詢:

http://localhost: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": ""
          }
        ]
      }
    }
  }
}

使用多個詞典

如果您已經定義了多個字典,您可以在查詢中使用它們。

示例查詢:

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

在這個例子中,我們發(fā)送了字符串 '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 配置中。這個例子將建議名稱,并允許按類別過濾:

在 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>

示例-上下文過濾建議查詢:

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

suggester 只會帶回標記為“cat = memory”的產品的建議。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號