結果分群

分群元件實作和 API(參數)在 9.0 版中已大幅變更。請參考與您的 Solr 版本完全相符的 Solr 指南。

分群(或集群分析)外掛程式嘗試自動探索相關搜尋結果(文件)的群組,並為這些群組指派人類可讀取的標籤。

Solr 中的分群演算法會應用於每個單一查詢搜尋結果中包含的文件 - 這稱為線上分群。

針對給定查詢探索到的群組可以被視為動態分面。當一般分面困難(欄位值事先未知)或查詢本質上是探索性的時,這會很有幫助。請查看 Carrot2 專案的示範頁面,以查看實際搜尋結果分群的範例(視覺化中的群組已在右側的搜尋結果中自動探索,不涉及外部資訊)。

image

發送給系統的查詢是Apache Solr。很明顯,分面無法產生類似的群組集合,儘管這兩種技術的目標相似 - 讓使用者探索搜尋結果集合,並重新組織查詢或將焦點縮小到目前文件的子集。分群也類似於結果分組,它可以幫助深入了解搜尋結果,而不僅僅是前幾個結果。

模組

這透過 clustering Solr 模組提供,使用前需要啟用。

設定快速入門

分群擴充功能作為搜尋元件運作。它需要在 solrconfig.xml 中宣告和設定,例如

<searchComponent class="org.apache.solr.handler.clustering.ClusteringComponent" name="clustering">
  <lst name="engine">
    <str name="name">lingo</str>
    <str name="clustering.fields">title, content</str>
    <str name="clustering.algorithm">Lingo</str>
  </lst>
</searchComponent>

以上宣告了具有單一引擎的分群元件 - 可以宣告多個引擎並在執行時切換。我們稍後會回到如何設定引擎的詳細資訊。

分群元件必須附加到 SearchHandler,並透過屬性 clustering 明確啟用。請務必將其附加為處理器管道中的最後一個元件,如下所示

  <requestHandler name="/select" class="solr.SearchHandler">
    <lst name="defaults">
      <bool name="clustering">true</bool>
      <str name="clustering.engine">lingo</str>
    </lst>

    <arr name="last-components">
      <str>clustering</str>
    </arr>
  </requestHandler>

一旦附加(如以上範例所示),分群將在所有符合搜尋處理器查詢的文件上自動執行。分群擴充功能將考量引擎的 clustering.fields 參數中列出的所有文字欄位,並產生一個名為 clusters 的回應區段,其中包含探索到的群組結構,例如(JSON 回應為簡潔起見)

{
    "clusters": [
        {
          "labels": ["Memory"],
          "score": 6.80,
          "docs":[ "0579B002",
            "EN7800GTX/2DHTV/256M",
            "TWINX2048-3200PRO",
            "VDBDB1A16",
            "VS1GB400C3"]},
        {
          "labels":["Coins and Notes"],
          "score":28.560285143284457,
          "docs":["EUR",
            "GBP",
            "NOK",
            "USD"]},
        {
          "labels":["TFT LCD"],
          "score":15.355729924203429,
          "docs":["3007WFP",
            "9885A004",
            "MA147LL/A",
            "VA902B"]}
    ]
}

每個叢集的 labels 元素是一個動態探索到的短語,描述並適用於 docs 元素下的所有文件識別碼。

Solr 發行範例

Solr 隨附的「techproducts」範例已預先設定所有必要的結果分群元件 - 但預設為停用。

若要啟用分群元件擴充功能以及設定為使用它的專用搜尋處理器,請在執行範例時指定 JVM 系統屬性

bin/solr start -e techproducts -Dsolr.clustering.enabled=true

您現在可以透過在瀏覽器中開啟下列 URL 來試用分群處理器

https://127.0.0.1:8983/solr/techproducts/clustering?q=*:*&rows=100&wt=xml

輸出 XML 應包含搜尋結果,最後還有一個自動探索到的群組陣列,類似於此處顯示的輸出

<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">299</int>
  </lst>
  <result name="response" numFound="32" start="0" maxScore="1.0">
    <doc>
      <str name="id">GB18030TEST</str>
      <str name="name">Test with some GB18030 encoded characters</str>
      <arr name="features">
        <str>No accents here</str>
        <str>这是一个功能</str>
        <str>This is a feature (translated)</str>
        <str>这份文件是很有光泽</str>
        <str>This document is very shiny (translated)</str>
      </arr>
      <float name="price">0.0</float>
      <str name="price_c">0,USD</str>
      <bool name="inStock">true</bool>
      <long name="_version_">1448955395025403904</long>
      <float name="score">1.0</float>
    </doc>

    <!-- more search hits, omitted -->
  </result>

  <arr name="clusters">
    <lst>
      <arr name="labels">
        <str>DDR</str>
      </arr>
      <double name="score">3.9599865057283354</double>
      <arr name="docs">
        <str>TWINX2048-3200PRO</str>
        <str>VS1GB400C3</str>
        <str>VDBDB1A16</str>
      </arr>
    </lst>
    <lst>
      <arr name="labels">
        <str>iPod</str>
      </arr>
      <double name="score">11.959228467119022</double>
      <arr name="docs">
        <str>F8V7067-APL-KIT</str>
        <str>IW-02</str>
        <str>MA147LL/A</str>
      </arr>
    </lst>

    <!-- More clusters here, omitted. -->

    <lst>
      <arr name="labels">
        <str>Other Topics</str>
      </arr>
      <double name="score">0.0</double>
      <bool name="other-topics">true</bool>
      <arr name="docs">
        <str>adata</str>
        <str>apple</str>
        <str>asus</str>
        <str>ati</str>
        <!-- other unassigned document IDs here -->
      </arr>
    </lst>
  </arr>
</response>

針對此查詢 (*:*) 發現了一些叢集,將所有搜尋結果區分為不同類別:DDR、iPod、硬碟等。每個叢集都有一個標籤和分數,表示該叢集的「優良程度」。分數是特定於演算法的,並且僅在同一組中其他叢集的分數之間才有意義。換句話說,如果叢集 A 的分數高於叢集 B,則叢集 A 的品質應該更好(具有更好的標籤和/或更一致的文件集)。每個叢集都有一組屬於它的文件識別碼。這些識別碼對應於 schema 中宣告的 uniqueKey 欄位。

有時叢集標籤可能沒有太大意義(這取決於許多因素 — 叢集欄位中的文字、文件數量、演算法參數)。此外,某些文件可能會被遺漏,根本不會被叢集;這些文件將被分配到合成的其他主題群組,並以 other-topics 屬性設定為 true 來標記(有關範例,請參閱上面的 XML 轉儲)。其他主題群組的分數為零。

組態

元件組態

以下屬性控制 ClusteringComponent 的狀態。

clustering

選填

預設值:false

即使已正確宣告並附加到搜尋處理常式,該元件預設也會停用。必須將 clustering 屬性設定為 true 才能啟用它。這可以透過在搜尋處理常式中設定預設參數來完成,如下一節所述。

clustering.engine

選填

預設值:請參閱說明

宣告要使用的引擎。如果不存在,則使用第一個宣告的活動引擎。

叢集引擎

solrconfig.xml 中叢集元件的宣告必須包含一個或多個預先定義的組態,稱為引擎。例如,考慮下面的組態

<searchComponent class="org.apache.solr.handler.clustering.ClusteringComponent" name="clustering">
  <lst name="engine">
      <str name="name">lingo</str>
      <str name="clustering.algorithm">Lingo</str>
      <str name="clustering.fields">title, content</str>
  </lst>

  <lst name="engine">
      <str name="name">stc</str>
      <str name="clustering.algorithm">STC</str>
      <str name="clustering.fields">title</str>
  </lst>
</searchComponent>

這宣告了兩個單獨的引擎(lingostc):這些組態具有不同的叢集演算法和一組不同的叢集文件欄位。可以透過在執行時(透過 URL)或在搜尋處理常式的組態中,傳遞 clustering.engine=name 參數來選擇活動引擎,如下所示

<requestHandler name="/clustering" class="solr.SearchHandler">
  <lst name="defaults">
    <!-- Clustering component enabled. -->
    <bool name="clustering">true</bool>
    <str name="clustering.engine">stc</str>

    <!-- Cluster the top 100 search results - bump up the 'rows' parameter. -->
    <str name="rows">100</str>
  </lst>

  <!-- Append clustering at the end of the list of search components. -->
  <arr name="last-components">
    <str>clustering</str>
  </arr>
</requestHandler>

叢集引擎組態參數

可以使用下面描述的許多參數來組態每個宣告的引擎。

clustering.fields

必填

預設值:無

以逗號(或空格)分隔的文字欄位清單,其中應包含用於叢集的文字內容。必須至少提供一個欄位。這些欄位與搜尋處理常式的 fl 參數分開,因此叢集欄位不必包含在回應中。

clustering.algorithm

必填

預設值:無

叢集演算法是發現文件之間關係並形成人類可讀的叢集標籤的實際邏輯(實作)。此參數設定此引擎將使用的叢集演算法名稱。演算法透過 Carrot2 定義的服務擴充功能提供給 Solr。預設情況下,應提供以下開放原始碼演算法:LingoSTCBisecting K-Means。如果類別路徑上可用,則商業叢集演算法 Lingo3G 會插入同一個擴充點並且可以使用。

如何選擇叢集演算法?

選擇哪個演算法的問題取決於流量、預期的結果和輸入資料(每個演算法將對輸入進行稍微不同的叢集)。沒有哪個演算法是「最佳」的答案:Lingo3G 提供階層式叢集,而 Lingo 和 STC 提供平面叢集。STC 比 Lingo 快,但可以說產生較不直觀的叢集,Lingo3G 是最快的演算法,但不是免費或開放原始碼的…​ 嘗試並選擇一個適合您需求的演算法。

有關這些演算法的特性比較,請參閱以下連結

叢集元件會在啟動時列出所有可用的演算法、語言和演算法語言相容性。您可以查看啟動記錄,以查看您的 Solr 安裝中可用的內容。

clustering.maxLabels

選填

預設值:無

返回的叢集標籤最大數量(如果演算法返回更多標籤,則列表將被截斷)。預設情況下,返回所有標籤。

clustering.includeSubclusters

選填

預設值:無

如果為 true,則回應中會包含支援階層式叢集演算法的子叢集。false 僅返回頂層叢集。

clustering.includeOtherTopics

選填

預設值:true

如果為 true,則會形成並返回一個名為其他主題的合成叢集,其中包含所有未分配給任何其他叢集的文件。如果不需要此合成叢集,則可以將其設定為 false

clustering.resources

選填

預設值:無

演算法特定資源和組態檔案(停止字詞、其他詞彙資源、預設設定)的位置。此屬性預設為 null,並且所有資源都從其各自的演算法預設資源池(JAR)讀取。如果此屬性不為空,則會相對於 Solr 核心的組態目錄解析。此參數只能在 Solr 啟動期間套用,不能按請求覆寫。

還有更多適用於引擎組態的屬性。我們將在後續的功能章節中描述這些屬性。

完整欄位和查詢內容 (程式碼片段) 叢集

叢集演算法可以使用欄位的完整內容,或僅使用查詢比對區域周圍的左側和右側內容(所謂的程式碼片段)。與直覺相反,即使向演算法提供較少的資料,使用查詢內容也可以提高叢集的品質。這通常是由於程式碼片段更集中在查詢周圍的片語和詞彙,並且演算法具有更好的資料訊號雜訊比可供使用。

我們建議當欄位包含大量內容時使用查詢內容(這會影響叢集效能)。

以下三個屬性控制是否處理內容或完整內容,以及如何形成用於叢集的程式碼片段。

clustering.preferQueryContext

選填

預設值:無

如果為 true,則引擎會嘗試擷取查詢比對區域周圍的內容,並將這些內容用作叢集演算法的輸入。

clustering.contextSize

選填

預設值:無

內容擷取演算法(內部螢光筆)建立的每個程式碼片段的最大大小(以字元為單位)。

clustering.contextCount

選填

預設值:無

單一欄位中不同、非連續程式碼片段的最大數量。

預設叢集語言

Carrot2 中叢集演算法的預設實作(與 Solr 一起提供)具有內建支援(詞幹、停止字詞)來預處理許多語言。重要的是為叢集演算法提供一個關於叢集應使用哪種語言的提示。這可以透過兩種方式完成 — 傳遞預設語言的名稱或為每個文件提供一個帶有語言的欄位。以下兩個引擎組態參數控制此項

clustering.language

選填

預設值:English

用於叢集的預設語言名稱。提供的語言必須可用,並且叢集演算法必須支援它。

clustering.languageField

選填

預設值:無

儲存文件語言的文件欄位名稱。如果文件不存在該欄位或值為空白,則使用預設語言。

支援語言的清單可以動態變更(語言透過外部服務提供者擴充功能載入),並且可能取決於所選的演算法(演算法可以支援資源可用的語言子集)。叢集元件會在 Solr 啟動時記錄所有支援的演算法語言對,因此您可以檢查您的特定 Solr 執行個體上支援的內容。例如

2020-10-29 [...] Clustering algorithm Lingo3G loaded with support for the following languages: Dutch, English
2020-10-29 [...] Clustering algorithm Lingo loaded with support for the following languages: Danish, Dutch, English, Finnish, French, German, Hungarian, Italian, Norwegian, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish
2020-10-29 [...] Clustering algorithm Bisecting K-Means loaded with support for the following languages: Danish, Dutch, English, Finnish, French, German, Hungarian, Italian, Norwegian, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish

處理多語言內容

索引(和查詢結果)通常包含多種語言的文件。叢集此類搜尋結果是有問題的。理想情況下,引擎應翻譯(或理解)文件的內容,然後將相關資訊分組在一起,而無論其撰寫的語言為何。

實際上,叢集演算法通常簡單得多 — 它們從這些文件中出現的詞彙和片語的統計特性推斷文件之間的相似性。因此,用不同語言編寫的文字不會叢集得太好。

為了處理這種情況,Solr 中的預設叢集元件實作會嘗試先按語言對所有文件進行分組,然後將叢集套用至該語言中的每個子群組。建議將每個文件的語言儲存為其單獨的欄位,並使用上面描述的 clustering.languageField 組態屬性指向它。

調整演算法設定

Solr 隨附的叢集演算法使用其預設參數值和語言資源。我們強烈建議針對生產用途進行調整。改進預設語言資源以包含特定文件網域常用的字詞和片語將顯著提高叢集品質。

Carrot2 演算法具有廣泛的參數和語言資源調整選項。請參閱 最新專案文件。特別是語言資源部分和每個演算法的屬性部分。

變更叢集演算法參數

叢集演算法設定可以透過 Solr 參數永久變更(在引擎宣告中)或按請求變更(透過 Solr URL 參數)。

例如,假設有以下引擎組態

<lst name="engine">
  <str name="name">lingo</str>
  <str name="clustering.algorithm">Lingo</str>
  <str name="clustering.fields">name, features</str>
  <str name="clustering.language">English</str>
</lst>

首先,在 Carrot2 文件網站上找到 Lingo 演算法的組態參數

image

然後找到您要變更的特定設定,並記下該設定的 REST API 路徑(在此情況下,參數為 minClusterSize,其路徑為 preprocessing.documentAssigner.minClusterSize

image

現在將完整的路徑值配對新增至引擎的組態中

<lst name="engine">
  <str name="name">lingo</str>
  <str name="clustering.algorithm">Lingo</str>
  <str name="clustering.fields">name, features</str>
  <str name="clustering.language">English</str>

  <int name="preprocessing.documentAssigner.minClusterSize">3</int>
</lst>

以下規則適用。

  • 參數的類型必須與 Carrot2 規格中列出的類型一致。

  • 如果參數是在 solrconfig.xml 中新增至引擎的組態,則必須重新載入核心,變更才會生效。或者,透過請求 URL 傳遞參數,以在每個請求的基礎上動態變更設定。例如,如果您正在執行「techproducts」範例,這將會將叢集縮減為僅包含至少三個文件的叢集:https://127.0.0.1:8983/solr/techproducts/clustering?q=*:*&rows=100&wt=json&preprocessing.documentAssigner.minClusterSize=3

  • 對於複雜類型,具有實例化類型名稱的參數鍵必須先於其任何自身的參數。

自訂語言資源

叢集演算法依賴於語言和特定領域的語言資源,以提高叢集的品質(透過捨棄特定領域的雜訊和樣板語言)。

預設情況下,語言資源是從引擎宣告的演算法預設 JAR 讀取。您可以透過指定 clustering.resources 參數來傳遞這些資源的自訂位置。此參數的值會解析為相對於 Solr 核心組態目錄的位置。例如,以下定義

<lst name="engine">
  <str name="name">lingo</str>
  <str name="clustering.algorithm">Lingo</str>
  <str name="clustering.fields">name, features</str>
  <str name="clustering.language">English</str>

  <str name="clustering.resources">lingo-resources</str>
</lst>

將產生以下記錄項目和預期的資源位置

Clustering algorithm resources first looked up relative to: [.../example/techproducts/solr/techproducts/conf/lingo-resources]

開始調整演算法資源的最佳方式是從其對應的 Carrot2 JAR 檔案(或 Carrot2 發行版本)複製所有預設值。

效能考量

搜尋結果的叢集化會帶來一些效能考量

  • 擷取大於平常數量的搜尋結果(50、100 或更多文件)的成本,

  • 叢集化本身的額外計算成本。

  • 在分散式模式下,用於叢集化的文件欄位內容是從分片收集的,這會增加一些額外的網路負擔。

對於簡單的查詢,叢集化時間通常會佔據其他所有時間。如果文件欄位非常長,則檢索儲存的內容可能會成為瓶頸。

可以透過幾種方式降低叢集化對效能的影響。

  • 減少叢集化的資料:使用查詢內容(程式碼片段)而不是完整的欄位內容 (clustering.preferQueryContext=true)。

  • 僅對部分文件欄位執行叢集化,或者為叢集化管理欄位(在建立索引時新增摘要),以縮減輸入大小。

  • 調整直接與特定演算法相關的效能屬性。

  • 嘗試使用不同的、更快的演算法(STC 而非 Lingo,Lingo3G 而非 STC)。

其他資源

以下資源提供了有關 Solr 中叢集元件及其潛在應用程式的更多資訊。