Solr收到的每個(gè)更新請(qǐng)求都通過一個(gè)稱為更新請(qǐng)求處理器或URP的一系列插件運(yùn)行。
例如,可以將字段添加到正在索引的文檔中,這是很有用的;改變特定字段的值; 或者如果傳入文檔不符合某些標(biāo)準(zhǔn),則刪除更新。實(shí)際上,Solr中出現(xiàn)了大量的特性被實(shí)現(xiàn)為更新處理器,因此有必要了解這些插件是如何工作的以及它們是如何配置的。
更新請(qǐng)求處理器是作為一個(gè)或多個(gè)更新處理器鏈的一部分創(chuàng)建的。Solr創(chuàng)建了一個(gè)默認(rèn)的更新請(qǐng)求處理器鏈,其中包含一些更新請(qǐng)求處理器,這些處理器支持基本的Solr功能。除非用戶選擇配置和指定不同的自定義更新請(qǐng)求處理器鏈,否則此默認(rèn)鏈用于處理每個(gè)更新請(qǐng)求。
描述更新請(qǐng)求處理器最簡單的方法是查看抽象類UpdateRequestProcessor的Javadoc 。每個(gè)UpdateRequestProcessor必須有一個(gè)相應(yīng)的factory類,它擴(kuò)展了UpdateRequestProcessorFactory。這個(gè)factory類被Solr用來創(chuàng)建這個(gè)插件的一個(gè)新實(shí)例。這樣的設(shè)計(jì)提供了以下兩個(gè)好處:
每個(gè)更新請(qǐng)求處理器鏈都是在加載Solr核心期間被構(gòu)建,并被緩存直到核心被卸載。在鏈中指定的每個(gè) UpdateRequestProcessorFactory 也會(huì)以 solrconfig. xml 中指定的配置進(jìn)行實(shí)例化和初始化。
當(dāng)Solr收到更新請(qǐng)求時(shí),它會(huì)查找用于此請(qǐng)求的更新鏈。在鏈中指定的每個(gè)UpdateRequestProcessor的新實(shí)例都使用相應(yīng)的factory創(chuàng)建。更新請(qǐng)求被解析成相應(yīng)的UpdateCommand對(duì)象,這些對(duì)象通過鏈接運(yùn)行。每個(gè)UpdateRequestProcessor實(shí)例負(fù)責(zé)調(diào)用鏈中的下一個(gè)插件。它可以通過不調(diào)用下一個(gè)處理器來選擇使鏈路短路,甚至通過拋出異常來中止進(jìn)一步的處理。
注意:單個(gè)更新請(qǐng)求可能包含多個(gè)新文檔或刪除的批次,因此,對(duì)于每個(gè)單獨(dú)的更新,UpdateRequestProcessor 的相應(yīng) processXXX 方法將被多次調(diào)用。但是,保證單個(gè)線程將依次調(diào)用這些方法。
更新請(qǐng)求處理器鏈可以通過在solrconfig.xml中直接創(chuàng)建整個(gè)鏈,或通過在solrconfig.xml中創(chuàng)建單獨(dú)的更新處理器來創(chuàng)建,然后通過請(qǐng)求參數(shù)指定所有處理器,在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建鏈。
但是,在我們了解如何配置更新處理器鏈之前,我們必須了解默認(rèn)更新處理器鏈,因?yàn)樗峁┝舜蠖鄶?shù)自定義請(qǐng)求處理器鏈中所需的基本功能。
如果沒有在solrconfig.xml配置更新處理器鏈,Solr將自動(dòng)創(chuàng)建一個(gè)默認(rèn)的更新處理器鏈,將用于所有更新請(qǐng)求。此默認(rèn)更新處理器鏈由以下處理器組成(按順序):
它們中的每一個(gè)都執(zhí)行基本的功能,因此任何定制鏈通常包含所有這些處理器。RunUpdateProcessorFactory通常是任何自定義鏈中的最后一次更新的處理器。
以下示例演示了如何在solrconfig.xml內(nèi)部配置自定義鏈。
重復(fù)數(shù)據(jù)刪除updateRequestProcessorChain示例:
<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>
在上述示例中,一個(gè)名為“重復(fù)數(shù)據(jù)刪除”的新的更新處理器鏈?zhǔn)鞘褂肧ignatureUpdateProcessorFactory、LogUpdateProcessorFactory 和 RunUpdateProcessorFactory在鏈中創(chuàng)建的。SignatureUpdateProcessorFactory 進(jìn)一步配置了不同的參數(shù),如“signatureField”,“overwriteDupes”等,此鏈?zhǔn)且粋€(gè)例子,說明 Solr 如何配置,可以通過使用名稱、功能和 cat 字段的值來計(jì)算簽名,然后將其用作
"id" 字段來執(zhí)行文檔重復(fù)數(shù)據(jù)消除。正如您可能已經(jīng)注意到的,這個(gè)鏈沒有指定 DistributedUpdateProcessorFactory。因?yàn)檫@個(gè)處理器對(duì)于Solr正常運(yùn)行至關(guān)重要,所以Solr會(huì)自動(dòng)在任何鏈中插入DistributedUpdateProcessorFactory,而不包括在 RunUpdateProcessorFactory 之前。
RunUpdateProcessorFactory:請(qǐng)不要忘記在您在 solrconfig. xml 中定義的任何鏈的末尾添加 RunUpdateProcessorFactory。否則,由該鏈處理的更新請(qǐng)求將不會(huì)實(shí)際影響索引數(shù)據(jù)。
更新請(qǐng)求處理器也可以獨(dú)立于 solrconfig. xml 中的鏈進(jìn)行配置。
updateProcessor 配置:
<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的一個(gè)實(shí)例被配置為名稱“signature” ,而 RemoveBlankFieldUpdateProcessorFactory 則用名稱 "remove_blanks" 定義。一旦在solrconfig.xml中指定了上述內(nèi)容,我們可以在solrconfig.xml更新請(qǐng)求處理器鏈中引用它們,如下所示:
updateRequestProcessorChain 配置:
<updateProcessorChain name="custom" processor="remove_blanks,signature">
<processor class="solr.RunUpdateProcessorFactory" />
</updateProcessorChain>
在一個(gè)獨(dú)立的Solr節(jié)點(diǎn)中,每次更新都會(huì)在鏈中的所有更新處理器中運(yùn)行一次。但是SolrCloud中更新請(qǐng)求處理器的行為值得特別考慮。
關(guān)鍵的SolrCloud功能是請(qǐng)求的路由和分配。對(duì)于更新請(qǐng)求,此路由由 DistributedUpdateRequestProcessor 實(shí)現(xiàn),并且由于它的重要功能,這個(gè)處理器被Solr給予一個(gè)特殊的狀態(tài)。
在SolrCloud模式,在 DistributedUpdateProcessor 之前鏈中的所有處理器都在從客戶端接收更新的第一個(gè)節(jié)點(diǎn)上運(yùn)行,而不管該節(jié)點(diǎn)作為前導(dǎo)或副本的狀態(tài)如何。DistributedUpdateProcessor隨后將更新轉(zhuǎn)發(fā)給相應(yīng)的碎片領(lǐng)導(dǎo)者(或在影響多個(gè)文檔(如通過查詢或提交來刪除)更新的情況下,向多個(gè)領(lǐng)導(dǎo)發(fā)送)。碎片領(lǐng)導(dǎo)使用事務(wù)日志來應(yīng)用原子更新和開放式并發(fā),然后將更新轉(zhuǎn)發(fā)給所有碎片副本。領(lǐng)導(dǎo)者和每個(gè)副本運(yùn)行鏈中列出的 DistributedUpdateProcessor 之后的所有處理器。
例如,考慮我們?cè)谏厦嬉还?jié)中看到的“重復(fù)數(shù)據(jù)刪除”鏈。假設(shè)存在一個(gè)3節(jié)點(diǎn)的SolrCloud集群,其中節(jié)點(diǎn)A承載shard1的引導(dǎo),節(jié)點(diǎn)B承載shard2的引導(dǎo),節(jié)點(diǎn)C承載shard2的副本。假設(shè)更新請(qǐng)求被發(fā)送到節(jié)點(diǎn)A,節(jié)點(diǎn)A將更新轉(zhuǎn)發(fā)到節(jié)點(diǎn)B(因?yàn)楦聦儆趕hard2),然后將更新分發(fā)到其副本節(jié)點(diǎn)C。讓我們看看在每個(gè)節(jié)點(diǎn)處發(fā)生了什么:
綜上所述:
在前一節(jié)中,我們看到了updateRequestProcessorChain 配置了processor="remove_blanks, signature"。這意味著這樣的處理器是 #1 類型的,只能在轉(zhuǎn)發(fā)節(jié)點(diǎn)上運(yùn)行。同樣,我們可以通過指定屬性“后處理器”來將它們配置為#2類型,如下所示:
后處理器(post-processors)配置:
<updateProcessorChain name="custom" processor="signature" post-processor="remove_blanks">
<processor class="solr.RunUpdateProcessorFactory" />
</updateProcessorChain>
然而,只在轉(zhuǎn)發(fā)節(jié)點(diǎn)上執(zhí)行處理器是一種很好的方法,它通過負(fù)載平衡器隨機(jī)發(fā)送請(qǐng)求,從而在SolrCloud集群上分配昂貴的計(jì)算(如重復(fù)數(shù)據(jù)刪除)。否則,會(huì)在領(lǐng)導(dǎo)節(jié)點(diǎn)和復(fù)制節(jié)點(diǎn)上重復(fù)進(jìn)行昂貴的計(jì)算。
不能在恢復(fù)的復(fù)制副本上調(diào)用自定義更新鏈post-processors:當(dāng)副本處于恢復(fù)狀態(tài)時(shí),入站更新請(qǐng)求將緩沖到事務(wù)日志中。成功完成恢復(fù)后,將重播那些緩沖的更新請(qǐng)求。但是,在編寫這篇文章時(shí),從不為緩沖的更新請(qǐng)求調(diào)用自定義更新鏈post-processors,見SOLR-8030。要解決此問題,直到SOLR-8030被修復(fù),請(qǐng)避免在自定義更新鏈中指定post-processors。
如果AtomicUpdateProcessorFactory是在 DistributedUpdateProcessor 之前的更新鏈中,則傳入的文檔鏈將是部分文檔。
由于DistributedUpdateProcessor負(fù)責(zé)將原子更新處理成領(lǐng)導(dǎo)者節(jié)點(diǎn)上的完整文檔,這意味著僅在轉(zhuǎn)發(fā)節(jié)點(diǎn)上執(zhí)行的預(yù)處理器只能對(duì)部分文檔進(jìn)行操作。如果您有一個(gè)必須處理完整文檔的處理器,那么唯一的選擇就是將其指定為post-processors。
該update.chain參數(shù)可用于任何更新請(qǐng)求中以選擇已在 solrconfig. xml 中配置的自定義鏈。例如,為了選擇上一節(jié)中描述的“重復(fù)數(shù)據(jù)刪除”鏈,可以發(fā)出以下請(qǐng)求:
使用update.chain:
curl "http://localhost: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"]
}
]'
上面應(yīng)該重復(fù)刪除兩個(gè)相同的文件,并且只索引其中的一個(gè)。
我們可以使用處理器和post-processor請(qǐng)求參數(shù)動(dòng)態(tài)地構(gòu)建自定義更新請(qǐng)求處理器鏈??梢詫⒍鄠€(gè)處理器指定為這兩個(gè)參數(shù)的逗號(hào)分隔值。例如:
執(zhí)行在solrconfig.xml中配置的處理器,比如:(pre)-processors
curl "http://localhost: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"]
}
]'
將solrconfig.xml中配置的處理器作為處理前和處理后執(zhí)行:
curl "http://localhost: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"]
}
]'
在第一個(gè)例子中,Solr將動(dòng)態(tài)地創(chuàng)建一個(gè)具有“signature”和“remove_blanks”的鏈作為預(yù)處理器,僅在轉(zhuǎn)發(fā)節(jié)點(diǎn)上執(zhí)行,而在第二個(gè)例子中,“remove_blanks”將作為預(yù)處理器并且“signature”將作為post-processor在領(lǐng)導(dǎo)者和副本上執(zhí)行。
我們還可以指定一個(gè)自定義鏈,默認(rèn)情況下用于發(fā)送到特定更新處理程序的所有請(qǐng)求,而不是在每個(gè)請(qǐng)求的請(qǐng)求參數(shù)中指定名稱。
這可以通過添加“update.chain”或“processor”和“post-processor”作為給定路徑的默認(rèn)參數(shù),可以通過 initParams 或通過在所有請(qǐng)求處理程序支持的 "default s" 部分中添加來完成。
以下initParam是在無模式配置中定義的,它將自定義更新鏈應(yīng)用于以“/update/”開頭的所有請(qǐng)求處理程序。
initParams示例:
<initParams path="/update/**">
<lst name="defaults">
<str name="update.chain">add-unknown-fields-to-the-schema</str>
</lst>
</initParams>
或者,可以使用下面的示例中顯示的“defaults”來實(shí)現(xiàn)類似的效果:
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>
以下是對(duì)當(dāng)前可用更新請(qǐng)求處理器的簡要說明。一個(gè)UpdateRequestProcessorFactory可以根據(jù)需要集成到 solrconfig. xml 中的更新鏈中。強(qiáng)烈要求您檢查這些類的Javadocs;這些描述是大部分取自Javadocs摘錄的片段。
如果輸入文檔包含一個(gè)或多個(gè)與模式中的任何字段或動(dòng)態(tài)字段不匹配的字段,則該處理器將動(dòng)態(tài)地向該模式添加字段。
該處理器將傳統(tǒng)的字段值文檔轉(zhuǎn)換為原子更新文檔。
這個(gè)處理器使用Lucene的分類模塊來提供簡單的文檔分類。有關(guān)如何使用此處理器的更多詳細(xì)信息,請(qǐng)參閱https://wiki.apache.org/solr/SolrClassification。
將在任何匹配的源字段中找到的值克隆到已配置的dest字段中。
一個(gè)簡單的處理器,它將一個(gè)默認(rèn)值添加到任何在fieldName中沒有值的文檔。
該Factory生成一個(gè)UpdateProcessor,該UpdateProcessor幫助使用版本字段的已配置名稱,基于每個(gè)文檔的版本號(hào)對(duì)文檔實(shí)施版本限制。
更新處理器工廠,用于管理文檔的自動(dòng)“expiration”。
通過用配置的replacement
替換與配置的pattern
匹配的所有匹配項(xiàng)來修改字段名稱。
允許您在SolrCloud模式下運(yùn)行時(shí)忽略提交或優(yōu)化來自客戶端應(yīng)用程序的請(qǐng)求,有關(guān)詳細(xì)信息,請(qǐng)參閱:SolrCloud中的碎片和索引數(shù)據(jù)
一個(gè)處理器將匹配“inputField”的內(nèi)容與在“boostFilename”中找到的正則表達(dá)式匹配,如果它匹配,則將從文件中返回相應(yīng)的boost值,并將其作為double值輸出到“boostField”。
使用一組定義的字段為文檔生成哈?!皊ignature”。用于索引“similar”文檔的一個(gè)副本。
更新請(qǐng)求處理器工廠,允許使用以腳本實(shí)現(xiàn)的更新處理器。
更新處理器,將新生成的日期值“NOW”添加到正在添加的文檔中,該文檔在指定的字段中沒有值。
更新處理器,檢查URL并輸出到具有該URL特征的其他各個(gè)字段,包括長度,路徑級(jí)別數(shù)量,是否是頂級(jí)URL(levels==0),是否看起來像登錄/索引頁面, URL的標(biāo)準(zhǔn)表示(例如,index.html),URL的域和路徑部分等。
更新處理器,將新生成的UUID值添加到正在添加的文檔中,該文檔在指定的字段中沒有值。
這些Factory都提供了修改文檔中的字段的功能。當(dāng)使用這些Factory時(shí),請(qǐng)參考FieldMutatingUpdateProcessorFactory的javadocs,了解它們都支持配置哪些字段被修改的常用選項(xiàng)。
使用可配置的分隔符連接多個(gè)值,以匹配指定條件的字段。
用與該字段的值的數(shù)量相同的值替換與指定的條件匹配的字段的值的任何列表。
使用這些CharSequences的長度(作為整數(shù))替換在指定條件中找到的所有CharSequence值。
只保留符合指定條件的字段的第一個(gè)值。
在符合指定條件的字段中找到的任何CharSequence值中剝離所有HTML標(biāo)記。
忽略并刪除正在添加到索引的任何文檔中符合指定條件的字段。
只保留匹配指定條件的字段的最后一個(gè)值。
更新處理器,只保留找到多個(gè)值的任何選定字段的最大值。
更新處理器,只保留找到多個(gè)值的任何選定字段的最小值。
嘗試將只有CharSequence類型值的選定字段變?yōu)椴紶栔怠?/p>
嘗試將僅具有CharSequence類型值的選定字段變?yōu)镾olr日期值。
嘗試將具有僅CharSequence類型值的選定字段變?yōu)镈ouble值。
嘗試將具有僅CharSequence類型的值的選定字段變?yōu)镕loat值。
嘗試將僅具有CharSequence類型值的選定字段變?yōu)镮nteger值。
嘗試將具有僅CharSequence類型的值的選定字段變?yōu)長ong值。
更新處理器,用配置的格式解析器分析使用PreAnalyzedField添加的任何文檔的配置字段。
更新后的處理器,將配置的正則表達(dá)式應(yīng)用于在所選字段中找到的任何CharSequence值,并用配置的替換字符串替換任何匹配項(xiàng)。
刪除找到的長度為0的CharSequence的任何值(即:空字符串)。
從匹配指定條件的字段中找到的任何CharSequence值修剪前導(dǎo)和尾隨空白。
將匹配指定條件的字段中的所有CharSequence值截?cái)酁樽畲笞址L度。
刪除在符合指定條件的字段中找到的重復(fù)值。
這些處理器作為“contribs”包含在Solr發(fā)行版中,并且需要在運(yùn)行時(shí)加載額外的jar。有關(guān)詳細(xì)信息,請(qǐng)參閱與每個(gè)contrib關(guān)聯(lián)的README文件:
langid
contrib 提供使用http://code.google.com/p/language-detection標(biāo)識(shí)一組輸入字段的語言。
使用Tika的LanguageIdentifier標(biāo)識(shí)一組輸入字段的語言。
uima
contrib請(qǐng)?zhí)峁?br>
使用UIMA提取的信息更新要編入索引的文檔。
這些是為完整性而列出的,但是是Solr基礎(chǔ)設(shè)施的一部分,特別是SolrCloud。除了確保在修改更新請(qǐng)求處理程序(或您創(chuàng)建的任何副本)時(shí)不要?jiǎng)h除它們,您將很少需要更改這些處理程序。
用于將更新分發(fā)到所有必需的節(jié)點(diǎn)。
一個(gè)DistributingUpdateProcessorFactory
的替代的No-Op實(shí)現(xiàn),總是返回null。專為希望繞過分布式更新并使用自己的自定義更新邏輯的用戶而設(shè)計(jì)。
記錄處理器。這將跟蹤所有已經(jīng)通過鏈的命令,并在finish()上打印它們。
使用底層的UpdateHandler執(zhí)行更新命令。幾乎所有的處理器鏈都應(yīng)該以一個(gè)RunUpdateProcessorFactory
實(shí)例結(jié)束,除非用戶在另一個(gè)自定義UpdateRequestProcessorFactory
中顯式執(zhí)行更新命令。
這些更新處理器不需要任何配置,就是您的solrconfig.xml。當(dāng)它們的名字被添加到processor參數(shù)時(shí),它們會(huì)自動(dòng)初始化。通過附加多個(gè)處理器名稱可以使用多個(gè)處理器(用逗號(hào)分隔)
該TemplateUpdateProcessorFactory可用于新的字段添加到基于模板的格式的文檔的。
使用參數(shù)processor=template來使用它。模板參數(shù)template.field(多值)定義要添加的字段和模式。模板可能包含引用文檔中其他字段的占位符。您可以在一個(gè)請(qǐng)求中使用多個(gè)Template.field參數(shù)。
例如:
processor=template&template.field=fullName:Mr. {firstName} {lastName}
上面的例子會(huì)在文檔中添加一個(gè)新的字段fullName。這些字段firstName 和 lastName是從文檔字段提供的。如果其中任何一個(gè)丟失,則該部分將被替換為空字符串。如果這些字段是多值的,則只使用第一個(gè)值。
處理器的名字是atomic。使用它將您的正常update操作轉(zhuǎn)換為原子更新操作。當(dāng)您使用諸如/update/csv或/update/json/docs不支持原子操作語法的端點(diǎn)時(shí),這一點(diǎn)特別有用。
例如:
processor=atomic&atomic.field1=add&atomic.field2=set&atomic.field3=inc&atomic.field4=remove&atomic.field4=remove
以上參數(shù)轉(zhuǎn)換為正常update操作
更多建議: