外部檔案與程序

Solr 支援使用名為 ExternalFileFieldType 的欄位類型將欄位值儲存在外部檔案中。它也可以使用名為 PreAnalyzedFieldType 的欄位類型來使用已分析的詞彙串流。

ExternalFileField 類型

ExternalFileField 類型可以讓您在 Solr 索引之外的檔案中指定欄位的值。對於此類欄位,該檔案包含從鍵值欄位到欄位值的對應。另一種思考方式是,Solr 並非在索引文件時指定文件中的欄位,而是從外部檔案中找到此欄位的值。

外部欄位無法搜尋。它們只能用於函數查詢或顯示。有關函數查詢的更多資訊,請參閱函數查詢一節。

當您想要比更新文件的其餘部分更頻繁地更新許多文件中的特定欄位時,ExternalFileField 類型很方便。例如,假設您已根據檢視次數實作文件排名。您可能想要每天或每小時更新所有文件的排名,而文件的其餘內容的更新頻率可能低得多。如果沒有 ExternalFileField,您需要更新每個文件才能變更排名。使用 ExternalFileField 效率更高,因為特定欄位的所有文件值都儲存在外部檔案中,您可以根據需要頻繁更新該檔案。

綱要中,此欄位類型的定義可能如下所示

<fieldType name="entryRankFile" keyField="pkId" defVal="0" stored="false" indexed="false" class="solr.ExternalFileField"/>

keyField 屬性定義將在外部檔案中定義的鍵值。它通常是索引的唯一鍵值,但不一定需要,只要 keyField 可以用來識別索引中的文件即可。defVal 定義一個預設值,如果特定文件在外部檔案中沒有對應項目,則會使用該預設值。

外部檔案格式

檔案本身位於 Solr 的索引目錄中,預設為 $SOLR_HOME/data。檔案名稱應為 external_fieldnameexternal_fieldname.*。以上述範例而言,該檔案可以命名為 external_entryRankFileexternal_entryRankFile.txt

如果出現任何使用名稱模式 .* (例如 .txt) 的檔案,則會使用最後一個 (依名稱排序後) 檔案,而先前的版本將會刪除。此行為支援在可能無法覆寫檔案的系統上進行實作 (例如,在 Windows 上,如果檔案正在使用中)。

該檔案包含將等號左側的鍵值欄位對應到右側的值的項目。以下是一些範例項目

doc33=1.414
doc34=3.14159
doc40=42

此檔案中列出的鍵值不一定要是唯一的。該檔案不需要排序,但如果經過排序,Solr 將能夠更快地執行查閱。

重新載入外部檔案

可以定義一個事件接聽器,以便在重新載入搜尋器或啟動新的搜尋器時重新載入外部檔案。請參閱查詢相關的接聽器一節,瞭解更多資訊,但 solrconfig.xml 中的範例定義可能如下所示

<listener event="newSearcher" class="org.apache.solr.schema.ExternalFileFieldReloader"/>
<listener event="firstSearcher" class="org.apache.solr.schema.ExternalFileFieldReloader"/>

PreAnalyzedField 類型

PreAnalyzedField 類型提供了一種將序列化詞元流傳送到 Solr 的方式,可選擇性地包含欄位的獨立儲存值,並且讓這些資訊在 Solr 中儲存和索引,而無需進行額外的文字處理。如果使用者想要提交已經由現有外部文字處理管道處理過的欄位內容(例如,已經過分詞、標註、詞幹提取、插入同義詞等),同時使用 Lucene 的 TokenStream 提供的所有豐富屬性(每個詞元屬性),這會很有用。

序列化格式可透過實作 PreAnalyzedParser 介面來外掛。有兩種開箱即用的實作:

  • JsonPreAnalyzedParser:顧名思義,它會解析使用 JSON 來表示欄位內容的內容。如果沒有另外設定欄位類型,這是預設要使用的解析器。

  • SimplePreAnalyzedParser:使用簡單的嚴格純文字格式,在某些情況下,這種格式可能比 JSON 更容易建立。

只有一個設定參數 parserImpl。此參數的值應該是實作 PreAnalyzedParser 介面的類別的完整類別名稱。此參數的預設值為 org.apache.solr.schema.JsonPreAnalyzedParser

預設情況下,此類型的欄位的查詢時分析器將與索引時分析器相同,後者期望序列化的預先分析文字。您必須在您的 fieldType 中新增一個查詢類型分析器,才能對非預先分析的查詢執行分析。在下面的範例中,索引時分析器期望預設的 JSON 序列化格式,而查詢時分析器將採用 StandardTokenizer/LowerCaseFilter。

<fieldType name="pre_with_query_analyzer" class="solr.PreAnalyzedField">
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

JsonPreAnalyzedParser

這是 PreAnalyzedField 類型使用的預設序列化格式。它使用具有下列鍵的頂層 JSON 對應:

描述 必要

v

版本鍵。目前支援的版本為 1

必要

str

欄位的儲存字串值。您最多可以使用 strbin 其中一個。

選用

bin

欄位的儲存二進位值。二進位值必須以 Base64 編碼。

選用

tokens

序列化詞元流。這是 JSON 清單。

選用

任何其他頂層鍵都會被靜默忽略。

詞元流序列化

詞元流表示為 JSON 對應的 JSON 清單。每個詞元的對應包含下列鍵和值:

描述 Lucene 屬性 必要?

t

詞元

CharTermAttribute

代表目前詞元的 UTF-8 字串

必要

s

起始偏移

OffsetAttribute

非負整數

選用

e

結束偏移

OffsetAttribute

非負整數

選用

i

位置增量

PositionIncrementAttribute

非負整數 - 預設值為 1

選用

p

酬載

PayloadAttribute

Base64 編碼的酬載

選用

y

詞彙類型

TypeAttribute

UTF-8 字串

選用

f

旗標

FlagsAttribute

以十六進位格式表示整數值的字串

選用

任何其他鍵都會被靜默忽略。

JsonPreAnalyzedParser 範例

{
  "v":"1",
  "str":"test ąćęłńóśźż",
  "tokens": [
    {"t":"two","s":5,"e":8,"i":1,"y":"word"},
    {"t":"three","s":20,"e":22,"i":1,"y":"foobar"},
    {"t":"one","s":123,"e":128,"i":22,"p":"DQ4KDQsODg8=","y":"word"}
  ]
}

SimplePreAnalyzedParser

透過 parserImpl 設定參數指定此格式時,要使用的完整類別名稱是 org.apache.solr.schema.SimplePreAnalyzedParser

SimplePreAnalyzedParser 語法

此解析器支援的序列化格式如下:

序列化格式
content ::= version (stored)? tokens
version ::= digit+ " "
; stored field value - any "=" inside must be escaped!
stored ::= "=" text "="
tokens ::= (token ((" ") + token)*)*
token ::= text ("," attrib)*
attrib ::= name '=' value
name ::= text
value ::= text

「文字」值中的特殊字元可以使用跳脫字元 \ 進行跳脫。可辨識下列跳脫序列:

跳脫序列 描述

\

字面空格字元

\,

字面 , 字元

\=

字面 = 字元

\\

字面 \ 字元

\n

換行

\r

歸位字元

\t

水平定位點

請注意,不支援 Unicode 序列(例如,\u0001)。

支援的屬性

支援下列詞元屬性,並以簡短的符號名稱識別:

名稱 描述 Lucene 屬性 值格式

i

位置增量

PositionIncrementAttribute

整數

s

起始偏移

OffsetAttribute

整數

e

結束偏移

OffsetAttribute

整數

y

詞彙類型

TypeAttribute

字串

f

旗標

FlagsAttribute

十六進位整數

p

酬載

PayloadAttribute

十六進位格式的位元組;會忽略空白字元

詞元位置會被追蹤並隱式新增至詞元流 - 起始和結束偏移僅考慮詞彙文字和空白字元,不包含詞元屬性所佔用的空間。

詞元流範例

1 one two three
  • 版本:1

  • 已儲存:null

  • 詞元:(term=one,startOffset=0,endOffset=3)

  • 詞元:(term=two,startOffset=4,endOffset=7)

  • 詞元:(term=three,startOffset=8,endOffset=13)

1 one  two    three
  • 版本:1

  • 已儲存:null

  • 詞元:(term=one,startOffset=0,endOffset=3)

  • 詞元:(term=two,startOffset=5,endOffset=8)

  • 詞元:(term=three,startOffset=11,endOffset=16)

1 one,s=123,e=128,i=22 two three,s=20,e=22
  • 版本:1

  • 已儲存:null

  • 詞元:(term=one,positionIncrement=22,startOffset=123,endOffset=128)

  • 詞元:(term=two,positionIncrement=1,startOffset=5,endOffset=8)

  • 詞元:(term=three,positionIncrement=1,startOffset=20,endOffset=22)

1 \ one\ \,,i=22,a=\, two\=

\n,\ =\ \
  • 版本:1

  • 已儲存:null

  • 詞元:(term=one ,,positionIncrement=22,startOffset=0,endOffset=6)

  • 詞元:(term=two= ,positionIncrement=1,startOffset=7,endOffset=15)

  • 詞元:(term=\,positionIncrement=1,startOffset=17,endOffset=18)

請注意,不明屬性和其值會被忽略,因此在此範例中,第一個詞元上的「a」屬性和第二個詞元上的「 」(跳脫空格)屬性,以及它們的值,都會被忽略,因為它們不在支援的屬性名稱中。

1 ,i=22 ,i=33,s=2,e=20 ,
  • 版本:1

  • 已儲存:null

  • 詞元:(term=,positionIncrement=22,startOffset=0,endOffset=0)

  • 詞元:(term=,positionIncrement=33,startOffset=2,endOffset=20)

  • 詞元:(term=,positionIncrement=1,startOffset=2,endOffset=2)

1 =This is the stored part with \=
\n \t escapes.=one two three
  • 版本:1

  • 已儲存:This is the stored part with = \t escapes.

  • 詞元:(term=one,startOffset=0,endOffset=3)

  • 詞元:(term=two,startOffset=4,endOffset=7)

  • 詞元:(term=three,startOffset=8,endOffset=13)

請注意,上述儲存值中的 \t 不是字面值;它以這種方式顯示是為了視覺上指出儲存值中的實際定位點字元。

1 ==
  • 版本:1

  • 已儲存:""

  • (沒有詞元)

1 =this is a test.=
  • 版本:1

  • 已儲存:this is a test.

  • (沒有詞元)