更新請求處理器
Solr 收到的每個更新請求都會經過一連串稱為更新請求處理器或URP的外掛程式。
這很有用,例如,在建立索引時為文件新增欄位;變更特定欄位的值;或者如果傳入的文件不符合特定條件,則捨棄更新。事實上,Solr 中許多功能都是以更新處理器的形式實作的,因此有必要了解這類外掛程式的運作方式以及其設定位置。
URP 結構和生命週期
更新請求處理器是作為一個或多個更新處理器鏈的一部分建立的。Solr 會建立一個包含幾個更新請求處理器的預設更新請求處理器鏈,這些處理器會啟用基本的 Solr 功能。除非使用者選擇設定和指定不同的自訂更新請求處理器鏈,否則此預設鏈會用於處理每個更新請求。
描述更新請求處理器最簡單的方法是查看抽象類別 UpdateRequestProcessor 的 Javadocs。每個 UpdateRequestProcessor 都必須有一個對應的工廠類別,該類別擴充自 UpdateRequestProcessorFactory。此工廠類別由 Solr 用於建立此外掛程式的新執行個體。這樣的設計有兩個好處
-
更新請求處理器不需要是執行緒安全的,因為它只由一個請求執行緒使用,並且在請求完成後就會銷毀。
-
工廠類別可以接受組態參數,並維護請求之間可能需要的任何狀態。工廠類別必須是執行緒安全的。
每個更新請求處理器鏈都會在載入 Solr 核心時建構,並快取直到核心卸載為止。鏈中指定的每個 UpdateRequestProcessorFactory
也會使用可能在 solrconfig.xml
中指定的設定來執行個體化和初始化。
當 Solr 接收到更新請求時,它會查找用於此請求的更新鏈。使用對應的工廠建立鏈中指定的每個 UpdateRequestProcessor 的新實例。更新請求會被解析為對應的 UpdateCommand 物件,這些物件會在鏈中執行。每個 UpdateRequestProcessor 實例負責調用鏈中的下一個外掛程式。它可以選擇不調用下一個處理器來短路鏈,甚至可以通過拋出例外來中止進一步的處理。
單個更新請求可能包含一批多個新文件或刪除,因此對於每個單獨的更新,UpdateRequestProcessor 的相應 processXXX 方法將被調用多次。但是,保證單個執行緒會依序調用這些方法。 |
更新請求處理器配置
更新請求處理器鏈可以通過以下兩種方式建立:直接在 solrconfig.xml
中建立整個鏈,或在 solrconfig.xml
中建立單獨的更新處理器,然後通過請求參數指定所有處理器,在執行時動態建立鏈。
但是,在了解如何配置更新處理器鏈之前,我們必須先了解預設的更新處理器鏈,因為它提供了大多數自訂請求處理器鏈中也需要的必要功能。
預設更新請求處理器鏈
如果 solrconfig.xml
中未配置任何更新處理器鏈,Solr 將自動建立一個預設的更新處理器鏈,該鏈將用於所有更新請求。此預設更新處理器鏈由以下處理器組成(按順序):
-
LogUpdateProcessorFactory
- 追蹤在此請求期間處理的命令並記錄它們 -
DistributedUpdateProcessorFactory
- 負責將更新請求分發到正確的節點,例如,將請求路由到正確分片的領導者,並將更新從領導者分發到每個副本。此處理器僅在 SolrCloud 模式下啟用。 -
RunUpdateProcessorFactory
- 使用內部 Solr API 執行更新。
這些處理器中的每一個都執行基本功能,因此任何自訂鏈通常都包含所有這些處理器。RunUpdateProcessorFactory
通常是任何自訂鏈中的最後一個更新處理器。
自訂更新請求處理器鏈
以下範例示範如何在 solrconfig.xml
內配置自訂鏈。
<updateRequestProcessorChain name="dedupe">
<processor class="solr.processor.SignatureUpdateProcessorFactory">
<bool name="enabled">true</bool>
<str name="signatureField">id</str>
<bool name="overwriteDupes">false</bool>
<str name="fields">name,features,cat</str>
<str name="signatureClass">solr.processor.Lookup3Signature</str>
</processor>
<processor class="solr.LogUpdateProcessorFactory" />
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
在上面的範例中,建立了一個名為「dedupe」的新更新處理器鏈,該鏈包含 SignatureUpdateProcessorFactory
、LogUpdateProcessorFactory
和 RunUpdateProcessorFactory
。SignatureUpdateProcessorFactory
進一步配置了不同的參數,例如「signatureField」、「overwriteDupes」等。此鏈是一個範例,說明如何配置 Solr 以通過計算使用 name、features、cat 欄位的值的簽名來執行文件的去重複,然後將其用作「id」欄位。您可能已經注意到,此鏈未指定 DistributedUpdateProcessorFactory
。由於此處理器對於 Solr 的正常運行至關重要,因此 Solr 會自動將 DistributedUpdateProcessorFactory
插入任何不包含它的鏈中,就在 RunUpdateProcessorFactory
之前。
RunUpdateProcessorFactory
不要忘記在 |
將單個處理器配置為頂級外掛程式
更新請求處理器也可以獨立於 solrconfig.xml
中的鏈進行配置。
<updateProcessor class="solr.processor.SignatureUpdateProcessorFactory" name="signature">
<bool name="enabled">true</bool>
<str name="signatureField">id</str>
<bool name="overwriteDupes">false</bool>
<str name="fields">name,features,cat</str>
<str name="signatureClass">solr.processor.Lookup3Signature</str>
</updateProcessor>
<updateProcessor class="solr.RemoveBlankFieldUpdateProcessorFactory" name="remove_blanks"/>
在這種情況下,SignatureUpdateProcessorFactory
的實例配置了名稱「signature」,並且 RemoveBlankFieldUpdateProcessorFactory
定義了名稱「remove_blanks」。在 solrconfig.xml
中指定以上內容後,我們可以在 solrconfig.xml
中的更新請求處理器鏈中引用它們,如下所示:
<updateProcessorChain name="custom" processor="remove_blanks,signature">
<processor class="solr.RunUpdateProcessorFactory" />
</updateProcessorChain>
SolrCloud 中的更新處理器
在使用者管理的叢集或單節點安裝中,每個更新都會在鏈中的所有更新處理器中正好執行一次。但是,在 SolrCloud 中,更新請求處理器的行為值得特別考慮。
SolrCloud 的一項關鍵功能是請求的路由和分發。對於更新請求,此路由由 DistributedUpdateRequestProcessor
實作,並且此處理器由於其重要功能而被 Solr 賦予特殊狀態。
在 SolrCloud 叢集中,在 DistributedUpdateProcessor
之前的鏈中的所有處理器都會在第一個接收到來自用戶端的更新的節點上執行,無論此節點作為領導者或副本的狀態如何。然後,DistributedUpdateProcessor
將更新轉發到適合更新的分片領導者(或在更新影響多個文件的情況下,例如通過查詢或提交刪除,則轉發到多個領導者)。分片領導者使用交易日誌應用部分文件更新,然後將更新轉發到所有分片副本。領導者和每個副本都會執行 DistributedUpdateProcessor
之後列出的鏈中的所有處理器。
例如,考慮我們在上面一節中看到的「dedupe」鏈。假設存在一個 3 節點的 SolrCloud 叢集,其中節點 A 主持 shard1 的領導者,節點 B 主持 shard2 的領導者,節點 C 主持 shard2 的 NRT 型副本。假設更新請求已傳送到節點 A,該節點將更新轉發到節點 B(因為更新屬於 shard2),然後將更新分發到其副本節點 C。讓我們看看每個節點上會發生什麼:
-
節點 A:通過
SignatureUpdateProcessor
(計算簽名並將其放入「id」欄位)、LogUpdateProcessor
和DistributedUpdateProcessor
執行更新。此處理器確定更新實際上屬於節點 B,並將其轉發到節點 B。更新不會進一步處理。這是必要的,因為下一個處理器RunUpdateProcessor
將對本地 shard1 索引執行更新,這將導致 shard1 和 shard2 上出現重複數據。 -
節點 B:接收更新並看到它是由另一個節點轉發的。更新會直接傳送到
DistributedUpdateProcessor
,因為它已經在節點 A 上通過了SignatureUpdateProcessor
,再次執行相同的簽名計算將是多餘的。DistributedUpdateProcessor
確定更新確實屬於此節點,將其分發到節點 C 上的副本,然後將更新進一步轉發到鏈中的RunUpdateProcessor
。 -
節點 C:接收更新並看到它是由其領導者分發的。更新會直接傳送到
DistributedUpdateProcessor
,該處理器會執行一些一致性檢查,並將更新進一步轉發到鏈中的RunUpdateProcessor
。
總結
-
在
DistributedUpdateProcessor
之前的所有處理器僅在接收到更新請求的第一個節點上執行,無論它是轉發節點(例如,上面範例中的節點 A)還是領導者(例如,節點 B)。我們將這些稱為「預處理器」或簡稱為「處理器」。 -
DistributedUpdateProcessor
之後的所有處理器僅在領導者和副本節點上執行。它們不會在轉發節點上執行。此類處理器稱為「後處理器」。
在上一節中,我們看到 updateRequestProcessorChain
配置了 processor="remove_blanks, signature"
。這表示此類處理器屬於第 1 類,並且僅在轉發節點上執行。同樣,我們可以通過使用屬性「post-processor」指定它們來將它們配置為第 2 類,如下所示:
<updateProcessorChain name="custom" processor="signature" post-processor="remove_blanks">
<processor class="solr.RunUpdateProcessorFactory" />
</updateProcessorChain>
但是,僅在轉發節點上執行處理器是一種通過負載平衡器隨機發送請求,在 SolrCloud 叢集上分發昂貴計算(例如去重複)的好方法。否則,昂貴的計算將在領導者和副本節點上重複執行。
自訂更新鏈後處理器可能永遠不會在正在復原的副本上調用
|
原子更新處理器工廠
如果 AtomicUpdateProcessorFactory
在 DistributedUpdateProcessor
之前的更新鏈中,則鏈的傳入文件將是部分文件。
由於 DistributedUpdateProcessor
負責將原子更新處理到領導者節點上的完整文件中,這表示僅在轉發節點上執行的預處理器只能對部分文件進行操作。如果您有一個必須處理完整文件的處理器,則唯一的選擇是將其指定為後處理器。
使用自訂鏈
update.chain 請求參數
update.chain
參數可用於任何更新請求,以選擇在 solrconfig.xml
中配置的自訂鏈。例如,為了選擇先前章節中描述的「dedupe」鏈,可以發出以下請求:
curl "https://127.0.0.1:8983/solr/gettingstarted/update/json?update.chain=dedupe&commit=true" -H 'Content-type: application/json' -d '
[
{
"name" : "The Lightning Thief",
"features" : "This is just a test",
"cat" : ["book","hardcover"]
},
{
"name" : "The Lightning Thief",
"features" : "This is just a test",
"cat" : ["book","hardcover"]
}
]'
以上內容應該會對兩個相同的文件進行去重複,並且只索引其中一個。
處理器 & 後處理器請求參數
我們可以使用 processor
和 post-processor
請求參數動態建構自訂的更新請求處理器鏈。可以為這兩個參數指定以逗號分隔的多個處理器。例如:
curl "https://127.0.0.1:8983/solr/gettingstarted/update/json?processor=remove_blanks,signature&commit=true" -H 'Content-type: application/json' -d '
[
{
"name" : "The Lightning Thief",
"features" : "This is just a test",
"cat" : ["book","hardcover"]
},
{
"name" : "The Lightning Thief",
"features" : "This is just a test",
"cat" : ["book","hardcover"]
}
]'
curl "https://127.0.0.1:8983/solr/gettingstarted/update/json?processor=remove_blanks&post-processor=signature&commit=true" -H 'Content-type: application/json' -d '
[
{
"name" : "The Lightning Thief",
"features" : "This is just a test",
"cat" : ["book","hardcover"]
},
{
"name" : "The Lightning Thief",
"features" : "This is just a test",
"cat" : ["book","hardcover"]
}
]'
在第一個範例中,Solr 會動態建立一個鏈,其中 "signature" 和 "remove_blanks" 作為前處理器,僅在轉發節點上執行;而在第二個範例中,"remove_blanks" 將作為前處理器執行,而 "signature" 將作為後處理器在領導者和副本上執行。
將自訂鏈配置為預設值
我們還可以指定一個自訂鏈,使其預設用於發送到特定更新處理器的所有請求,而不是在每個請求的請求參數中指定名稱。
這可以透過將 "update.chain" 或 "processor" 和 "post-processor" 作為給定路徑的預設參數來完成,這可以透過 InitParams 或在所有請求處理器都支援的"defaults" 區段中新增來完成。
以下是在 無結構描述模式中定義的 initParam
,它將自訂更新鏈應用於所有以 "/update/" 開頭的請求處理器。
<initParams path="/update/**">
<lst name="defaults">
<str name="update.chain">add-unknown-fields-to-the-schema</str>
</lst>
</initParams>
或者,可以使用以下範例中所示的 "defaults" 來實現類似的效果
<requestHandler name="/update/extract" startup="lazy" class="solr.extraction.ExtractingRequestHandler" >
<lst name="defaults">
<str name="update.chain">add-unknown-fields-to-the-schema</str>
</lst>
</requestHandler>
更新請求處理器工廠
以下是目前可用更新請求處理器的簡要描述。UpdateRequestProcessorFactory
可以根據需要在 solrconfig.xml
中整合到更新鏈中。強烈建議您檢閱這些類別的 Javadocs;這些描述大多是從 Javadocs 中摘錄的簡短片段。
通用更新處理器工廠
- AddSchemaFieldsUpdateProcessorFactory
-
如果輸入文件包含一個或多個與結構描述中的任何欄位或動態欄位不匹配的欄位,則此處理器會動態將欄位新增至結構描述。
- AtomicUpdateProcessorFactory
-
此處理器會將傳統的欄位值文件轉換為原子更新文件。此處理器可以在執行時使用(無需在
solrconfig.xml
中定義),請參閱以下 AtomicUpdateProcessorFactory 區段。 - ClassificationUpdateProcessorFactory
-
此處理器使用 Lucene 的分類模組來提供簡單的文件分類。請參閱 https://cwiki.apache.org/confluence/display/solr/SolrClassification 以了解有關如何使用此處理器的更多詳細資訊。
- CloneFieldUpdateProcessorFactory
-
將任何相符來源欄位中找到的值複製到已設定的目標欄位中。
- DefaultValueUpdateProcessorFactory
-
一個簡單的處理器,將預設值新增到任何在 fieldName 中尚未有值的文件。
- DocBasedVersionConstraintsProcessorFactory
-
此工廠會產生一個 UpdateProcessor,協助使用已設定的 versionField 名稱,根據每個文件的版本號強制執行文件的版本限制。
- DocExpirationUpdateProcessorFactory
-
用於管理文件自動「過期」的更新處理器工廠。
- FieldNameMutatingUpdateProcessorFactory
-
透過將所有與設定的
pattern
比對的結果替換為設定的replacement
來修改欄位名稱。 - IgnoreCommitOptimizeUpdateProcessorFactory
-
當在 SolrCloud 模式下執行時,允許您忽略來自用戶端應用程式的提交和/或最佳化請求,如需詳細資訊,請參閱:SolrCloud 中的分片和索引資料
- IgnoreLargeDocumentProcessorFactory
-
允許您防止大小超過
limit
(KB) 的大型文件被索引。它可以幫助防止索引和復原時因大型文件而導致的意外問題。預設情況下,如果此處理器遇到超過設定限制的文件,將會中止更新請求並將錯誤傳回給使用者。在違規者之前處理的文件將由 Solr 建立索引;違規者之後的文件將保持未處理。
或者,處理器提供「寬容」模式 (
permissiveMode=true
),該模式會跳過違規文件並記錄警告,但不會中止其餘批次或將錯誤傳回給使用者。 - NumFieldLimitingUpdateRequestProcessorFactory
-
一旦核心超過可設定的「最大」欄位數,則會使更新請求失敗。
如果核心累積過多(例如超過 500 個)欄位,Solr 的效能可能會降低甚至變得不穩定。「NumFieldLimiting」URP 作為一種保護措施,可協助使用者在這些效能和穩定性問題出現之前,注意到潛在的危險結構描述設計和/或濫用動態欄位。請注意,索引回報的欄位計數可能會受到已刪除(但尚未清除)文件的影響,並且可能因副本而異。為了避免副本之間出現這種差異,在 SolrCloud 模式下執行時,使用此 URP 幾乎應始終先於 DistributedUpdateProcessor。
- RegexpBoostProcessorFactory
-
一個處理器,會將「inputField」的內容與「boostFilename」中找到的正規表示式比對,如果比對成功,則會從檔案中傳回對應的 boost 值,並將此值以雙精度值輸出至「boostField」。
- SignatureUpdateProcessorFactory
-
使用定義的一組欄位來產生文件的雜湊「簽名」。適用於僅對「類似」文件的一個副本建立索引。
- ScriptUpdateProcessorFactory
-
一個處理器,可啟用使用以腳本實作的更新處理器。請在 腳本更新處理器 區段中了解更多資訊。
- TemplateUpdateProcessorFactory
-
允許根據範本模式將新欄位新增至文件。此更新處理器也可以在執行時使用(無需在
solrconfig.xml
中定義),請參閱以下 TemplateUpdateProcessorFactory 區段。 - TimestampUpdateProcessorFactory
-
一個更新處理器,可將新產生的「NOW」日期值新增至任何正在新增且指定欄位中尚未有值的文件。
- URLClassifyProcessorFactory
-
更新處理器,會檢查 URL 並將該 URL 的特性輸出到其他各種欄位,包括長度、路徑層級數、是否為頂級 URL (levels==0)、看起來是否像登入/索引頁面、URL 的標準表示法(例如,剝離 index.html)、URL 的網域和路徑部分等等。
- UUIDUpdateProcessorFactory
-
一個更新處理器,可將新產生的 UUID 值新增至任何正在新增且指定欄位中尚未有值的文件。此處理器也可以在執行時使用(無需在
solrconfig.xml
中定義),請參閱以下 UUIDUpdateProcessorFactory 區段。
FieldMutatingUpdateProcessorFactory 衍生的工廠
這些工廠都提供在文件建立索引時修改文件中欄位的功能。使用這些工廠中的任何一個時,請參閱 FieldMutatingUpdateProcessorFactory javadocs,以了解它們都支援的常見選項的詳細資訊,這些選項用於設定修改哪些欄位。
- ConcatFieldUpdateProcessorFactory
-
使用可設定的分隔符號,串連符合指定條件的欄位的多個值。
- CountFieldValuesUpdateProcessorFactory
-
將符合指定條件的欄位的所有值清單取代為該欄位的值數量。
- FieldLengthUpdateProcessorFactory
-
將符合指定條件的欄位中找到的任何 CharSequence 值取代為這些 CharSequence 的長度(以整數表示)。
- FirstFieldValueUpdateProcessorFactory
-
僅保留符合指定條件的欄位的第一個值。
- HTMLStripFieldUpdateProcessorFactory
-
剝離符合指定條件的欄位中找到的任何 CharSequence 值中的所有 HTML 標記。
- IgnoreFieldUpdateProcessorFactory
-
忽略並移除新增至索引的任何文件中符合指定條件的欄位。
- LastFieldValueUpdateProcessorFactory
-
僅保留符合指定條件的欄位的最後一個值。
- MaxFieldValueUpdateProcessorFactory
-
一個更新處理器,僅保留任何選取欄位中找到多個值時的最大值。
- MinFieldValueUpdateProcessorFactory
-
一個更新處理器,僅保留任何選取欄位中找到多個值時的最小值。
- ParseBooleanFieldUpdateProcessorFactory
-
嘗試將僅具有 CharSequence 類型值的選取欄位變換為布林值。
- ParseDateFieldUpdateProcessorFactory
-
嘗試將僅具有 CharSequence 類型值的選取欄位變換為日期值。
- ParseNumericFieldUpdateProcessorFactory 衍生類別
-
- ParseDoubleFieldUpdateProcessorFactory
-
嘗試將僅具有 CharSequence 類型值的選取欄位變換為雙精度值。
- ParseFloatFieldUpdateProcessorFactory
-
嘗試將僅具有 CharSequence 類型值的選取欄位變換為浮點值。
- ParseIntFieldUpdateProcessorFactory
-
嘗試將僅具有 CharSequence 類型值的選取欄位變換為整數值。
- ParseLongFieldUpdateProcessorFactory
-
嘗試將僅具有 CharSequence 類型值的選取欄位變換為長整數值。
- PreAnalyzedUpdateProcessorFactory
-
一個更新處理器,使用已設定格式的剖析器剖析新增的任何文件的設定欄位 (PreAnalyzedField)。
- RegexReplaceProcessorFactory
-
一個更新的處理器,會將設定的正規表示式套用至選取欄位中找到的任何 CharSequence 值,並將任何符合的結果取代為設定的取代字串。
- RemoveBlankFieldUpdateProcessorFactory
-
移除找到的任何長度為 0 的 CharSequence 值(即空字串)。
- TrimFieldUpdateProcessorFactory
-
修剪符合指定條件的欄位中找到的任何 CharSequence 值的前導和尾隨空白。
- TruncateFieldUpdateProcessorFactory
-
將符合指定條件的欄位中找到的任何 CharSequence 值截斷為最大字元長度。
- UniqFieldsUpdateProcessorFactory
-
移除符合指定條件的欄位中找到的重複值。
可以作為外掛程式載入的更新處理器工廠
這些處理器包含在 Solr 版本中作為「模組」,並需要在執行時載入其他 jar 檔案。請參閱每個模組相關聯的 README 檔案以了解詳細資訊
langid
模組提供-
- LangDetectLanguageIdentifierUpdateProcessorFactory
-
使用 http://code.google.com/p/language-detection 識別一組輸入欄位的語言。
- TikaLanguageIdentifierUpdateProcessorFactory
-
使用 Tika 的 LanguageIdentifier 識別一組輸入欄位的語言。
analysis-extras
模組提供-
- OpenNLPExtractNamedEntitiesUpdateProcessorFactory
-
更新要索引的文件,使其包含使用 OpenNLP NER 模型提取的命名實體。請注意,若要在 SolrCloud 上使用大於 1MB 的模型檔案,您必須設定 ZooKeeper 伺服器和用戶端,或者將模型檔案儲存在每個託管集合複本的節點的檔案系統上。
您不應修改或移除的更新處理器工廠
這些列出是為了完整性,但它們是 Solr 基礎架構的一部分,特別是 SolrCloud。除了確保您在修改更新請求處理器(或您所做的任何副本)時不要移除它們之外,您很少(如果有的話)需要更改這些。
- DistributedUpdateProcessorFactory
-
用於將更新分發到所有必要的節點。
- NoOpDistributingUpdateProcessorFactory
-
DistributingUpdateProcessorFactory
的替代 No-Op 實作,總是返回 null。專為想要繞過分散式更新並使用自己自訂更新邏輯的專家設計。
- LogUpdateProcessorFactory
-
一個日誌處理器。它會追蹤所有已通過鏈的命令,並在 finish() 時列印它們。
- RunUpdateProcessorFactory
-
使用底層 UpdateHandler 執行更新命令。除非使用者在替代的自訂
UpdateRequestProcessorFactory
中明確執行更新命令,否則幾乎所有的處理器鏈都應以RunUpdateProcessorFactory
的實例結束。
可以在執行時期使用的更新處理器
這些更新處理器不需要在 solrconfig.xml
中進行任何設定。當它們的名稱添加到與更新請求一起發送的 processor
參數時,它們會自動初始化。可以通過附加以逗號分隔的多個處理器名稱來使用多個處理器。
AtomicUpdateProcessorFactory
AtomicUpdateProcessorFactory
用於原子更新文件。
使用參數 processor=atomic
來調用它。用它來將您的常規 update
操作轉換為原子更新操作。當您使用 /update/csv
或 /update/json/docs
等端點時,這特別有用,因為這些端點本身沒有原子操作的語法。
例如
processor=atomic&atomic.field1=add&atomic.field2=set&atomic.field3=inc&atomic.field4=remove&atomic.field4=remove
上述參數以下列方式轉換常規的 update
操作
-
field1
為原子add
操作 -
field2
為原子set
操作 -
field3
為原子inc
操作 -
field4
為原子remove
操作
TemplateUpdateProcessorFactory
TemplateUpdateProcessorFactory
可以用於根據範本模式向文件新增欄位。
使用參數 processor=template
來使用它。範本參數 template.field
(多值) 定義要新增的欄位和模式。範本可以包含指向文件中其他欄位的佔位符。您可以在單個請求中有多個 Template.field
參數。
例如
processor=template&template.field=fullName:Mr. {firstName} {lastName}
上面的例子會向文件添加一個名為 fullName
的新欄位。 欄位 firstName
和 lastName
是從文件欄位提供的。如果其中任何一個遺失,則該部分將替換為空字串。如果這些欄位是多值的,則只會使用第一個值。