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