DocValues

DocValues 是一種內部記錄欄位值的方式,對於某些目的而言,例如排序和分面,比傳統索引更有效率。

為什麼需要 DocValues?

Solr 建構索引的標準方式是使用反向索引。這種方式會建立索引中所有文件中找到的詞彙清單,並且在每個詞彙旁邊列出該詞彙出現的文件 (以及該詞彙在該文件中出現的次數)。這使得搜尋速度非常快 - 由於使用者是透過詞彙進行搜尋,因此擁有現成的詞彙到文件值清單可以加快查詢處理速度。

對於我們現在通常與搜尋相關聯的其他功能 (例如排序、分面和醒目提示),這種方法效率不高。例如,分面引擎必須查詢每個會出現在結果集中的文件中出現的每個詞彙,並提取文件 ID 以建構分面清單。在 Solr 中,這是維護在記憶體中的,並且載入速度可能很慢 (取決於文件數、詞彙數等等)。

在 Lucene 4.0 中,引入了一種新方法。DocValue 欄位現在是欄導向的欄位,在索引時建構文件到值的對應。這種方法有望減輕 fieldCache 的一些記憶體需求,並使分面、排序和分組的查詢速度更快。

啟用 DocValues

當使用 schemaVersion >= 1.7 時,預設情況下會為大多數支援 DocValues 的欄位類型啟用 DocValues。
  • 基本欄位

    • Numeric (非 DenseVectorField)

    • 布林值

    • 字串

    • 日期

    • UUID

    • 列舉

  • 排序欄位

    • CollationField

    • ICUCollationField

    • SortableTextField

    • SortableBinaryField

  • LatLonPointSpacialField (非 PointType,它與 PointField 不同)

當使用較早的 schemaVersion (<= 1.6) 時,您只需要為要使用的欄位啟用 docValues 即可。與所有結構描述設計一樣,您需要定義欄位類型,然後定義啟用 docValues 的該類型的欄位。所有這些動作都在結構描述中完成。

啟用欄位的 docValues 功能,只需在欄位(或欄位類型)定義中加入 docValues="true" 即可,如下列 Solr 的 sample_techproducts_configs 設定集 中的範例所示。

<field name="manu_exact" type="string" indexed="false" stored="false" docValues="true" />
如果您已經將資料索引到 Solr 索引中,則在變更 schema 中的欄位定義後,您需要完全重新索引內容,才能成功使用 docValues。

DocValues 僅適用於特定的欄位類型。所選擇的類型會決定將使用的底層 Lucene docValue 類型。可用的 Solr 欄位類型如下:

  • StrFieldUUIDField

    • 如果欄位是單值的(即 multi-valued 為 false),Lucene 將使用 SORTED 類型。

    • 如果欄位是多值的,Lucene 將使用 SORTED_SET 類型。條目會以排序順序保留,並移除重複項。

  • BoolField:

    • 如果欄位是單值的(即 multi-valued 為 false),Lucene 將使用 SORTED 類型。

    • 如果欄位是多值的,Lucene 將使用 SORTED_SET 類型。條目會以排序順序保留,並移除重複項。

  • 任何 *PointField 數值或日期欄位、EnumFieldTypeCurrencyFieldType

    • 如果欄位是單值的(即 multi-valued 為 false),Lucene 將使用 NUMERIC 類型。

    • 如果欄位是多值的,Lucene 將使用 SORTED_NUMERIC 類型。條目會以排序順序保留,並保留重複項。

  • 任何已棄用的 Trie* 數值或日期欄位、EnumFieldCurrencyField

    • 如果欄位是單值的(即 multi-valued 為 false),Lucene 將使用 NUMERIC 類型。

    • 如果欄位是多值的,Lucene 將使用 SORTED_SET 類型。條目會以排序順序保留,並移除重複項。

這些 Lucene 類型與 值的排序和儲存方式有關。

還有一個額外的配置選項可用,即修改欄位類型所使用的 docValuesFormat。預設實作採用將某些內容載入記憶體,而將某些內容保留在磁碟上的混合方式。但在某些情況下,您可能會選擇指定替代的 DocValuesFormat 實作。例如,您可以選擇將所有內容保留在記憶體中,方法是在欄位類型上指定 docValuesFormat="Direct"

<fieldType name="string_in_mem_dv" class="solr.StrField" docValues="true" docValuesFormat="Direct" />

請注意,docValuesFormat 選項在未來的版本中可能會變更。

Lucene 索引的回溯相容性僅支援預設編碼器。如果您選擇在 schema 中自訂 docValuesFormat,則升級到未來版本的 Solr 可能需要您先切換回預設編碼器,並最佳化您的索引以將其重寫為預設編碼器,才能升級,或者在升級後從頭重新建立整個索引。

使用 DocValues

排序、分面與函數

如果欄位的 docValues="true",則每當欄位用於排序分面函數查詢時,將自動使用 DocValues。

在搜尋查詢期間擷取的欄位值通常是從儲存的值返回。但是,當指定返回所有欄位(或模式比對萬用字元)時(例如,針對搜尋查詢使用 "fl=*"),非儲存的 docValues 欄位也會與其他儲存的欄位一起返回,這取決於每個欄位的 useDocValuesAsStored 參數的有效值。對於 schema 版本 >= 1.6,隱式預設值為 useDocValuesAsStored="true"。如需詳細資訊,請參閱欄位類型定義與屬性欄位

useDocValuesAsStored="false" 時,非儲存的 DocValues 欄位仍然可以在 fl 參數中按名稱明確請求,但不會比對萬用字元模式 ("*")。

在查詢時返回 DocValues 與「常規」儲存的欄位會產生效能影響,因為 DocValues 是以欄導向的,因此可能需要額外成本才能為每個返回的文件擷取。

從 DocValues 返回非儲存欄位時,多值欄位的值會以排序順序返回,而不是插入順序,並且可能會移除重複項,請參閱上文。如果您要求多值欄位以原始插入順序返回,則請將多值欄位儲存起來(這種變更需要重新索引)。

在查詢返回 docValues 欄位的情況下,效能可能會提高,因為返回儲存的欄位需要磁碟讀取和解壓縮,而返回 fl 列表中的 docValues 欄位僅需要記憶體存取。

從其 docValues 形式擷取欄位時(例如使用 /export 處理常式串流運算式,或在 fl 參數中請求欄位時),必須了解常規儲存欄位與 docValues 欄位之間的兩個重要差異

  1. 順序會保留。擷取儲存的欄位時,插入順序是返回順序。對於 docValues,則是排序順序。

  2. 對於使用 SORTED_SET 的欄位類型(請參閱上文),多個相同的條目會折疊為單一值。因此,如果插入值 4、5、2、4、1,則返回的值將是 1、2、4、5。

停用 DocValues

對於所有支援的欄位類型,預設會啟用 DocValues(當使用 schemaVersion >= 1.7 時)。停用欄位或欄位類型上的 docValues,只需在定義中加入 docValues="false" 即可

<field name="field_a" type="string" docValues="false" />