使用更新處理器建立索引
更新處理器是設計用來新增、刪除和更新索引中文件的請求處理器。除了有匯入豐富文件的外掛程式(請參閱使用 Solr Cell 和 Apache Tika 建立索引)之外,Solr 原生支援索引 XML、CSV 和 JSON 格式的結構化文件。
建議配置和使用請求處理器的方式是使用基於路徑的名稱,這些名稱會對應到請求 URL 中的路徑。但是,如果 requestDispatcher
設定適當,也可以使用 qt
(查詢類型)參數指定請求處理器。可以使用多個名稱存取同一個處理器,如果您想要指定不同的預設選項集,這會很有用。
單一統一的更新請求處理器支援 XML、CSV、JSON 和 javabin 更新請求,並根據 ContentStream 的 Content-Type
委派給適當的 ContentStreamLoader
。
如果您需要在載入文件之後但在建立索引之前(甚至在針對結構描述檢查之前)預先處理文件,Solr 為更新請求處理器提供了文件預處理外掛程式,稱為 更新請求處理器,它們允許預設和自訂配置鏈。
UpdateRequestHandler 設定
預設的設定檔已預設配置更新請求處理器。
<requestHandler name="/update" class="solr.UpdateRequestHandler" />
XML 格式的索引更新
可以使用 Content-type: application/xml
或 Content-type: text/xml
,以 XML 訊息的形式將索引更新命令傳送至更新處理器。
新增文件
更新處理器為了新增文件而識別的 XML 結構描述非常簡單
-
<add>
元素引入一或多個要新增的文件。 -
<doc>
元素引入組成文件的欄位。 -
<field>
元素呈現特定欄位的內容。
例如
<add>
<doc>
<field name="authors">Patrick Eagar</field>
<field name="subject">Sports</field>
<field name="dd">796.35</field>
<field name="numpages">128</field>
<field name="desc"></field>
<field name="price">12.40</field>
<field name="title">Summer of the all-rounder: Test and championship cricket in England 1982</field>
<field name="isbn">0002166313</field>
<field name="yearpub">1982</field>
<field name="publisher">Collins</field>
</doc>
<doc>
...
</doc>
</add>
新增命令支援一些可指定的選用屬性。
commitWithin
-
選用
預設值:無
在指定的毫秒數內新增文件。
overwrite
-
選用
預設值:
true
指出是否應檢查唯一鍵約束來覆寫同一文件的先前版本(請參閱下文)。
如果文件結構描述定義了唯一鍵,則依預設,新增文件的 /update
操作會覆寫 (即取代) 索引中具有相同唯一鍵的任何文件。如果未定義唯一鍵,索引效能會稍微快一些,因為無需檢查是否有現有文件需要取代。
如果您有唯一鍵欄位,但您確信可以安全地略過唯一性檢查 (例如,您以批次方式建立索引,且您的索引程式碼保證永遠不會新增同一份文件一次以上),您可以在新增文件時指定 overwrite="false"
選項。
XML 更新指令
更新期間的提交與優化
<commit>
操作會將上次提交以來載入的所有文件寫入磁碟上的一個或多個段落檔案。在發出提交之前,新索引的內容對搜尋是不可見的。提交操作會開啟一個新的搜尋器,並觸發任何已設定的事件監聽器。
提交可以透過 <commit/>
訊息明確發出,也可以從 solrconfig.xml
中的 <autocommit>
參數觸發。
<optimize>
操作會要求 Solr 合併內部資料結構。對於大型索引,優化需要一些時間才能完成,但透過將許多小型段落檔案合併為較大的段落,搜尋效能可能會有所改善。如果您使用 Solr 的複寫機制在多個系統之間分散搜尋,請注意在優化之後,需要傳輸完整的索引。
您應該只考慮在靜態索引上使用優化,也就是可以作為常規更新程序的一部分進行優化的索引(例如,每日一次更新)。需要 NRT 功能的應用程式不應使用優化。 |
<commit>
和 <optimize>
元素接受這些可選屬性
waitSearcher
-
選用
預設值:
true
封鎖直到新的搜尋器開啟並註冊為主要的查詢搜尋器,使變更可見。
expungeDeletes
-
選用
預設值:
false
合併具有超過 10% 刪除文件的段落,並在此過程中清除已刪除的文件。產生的段落將遵循
maxMergedSegmentMB
。此選項僅適用於<commit>
操作中。expungeDeletes
比優化便宜,但同樣的警告也適用。 maxSegments
-
選用
預設值:無
盡最大努力將段落合併到不超過此數量的段落,但不保證能達到目標。除非有切實的證據表明優化為少量段落是有益的,否則應省略此參數並接受預設行為。此選項僅適用於
<optimize
操作。預設值為無限制,產生的段落遵循maxMergedSegmentMB
設定。
以下是使用可選屬性的 <commit>
和 <optimize>
的範例
<commit waitSearcher="false"/>
<commit waitSearcher="false" expungeDeletes="true"/>
<optimize waitSearcher="false"/>
刪除操作
可以透過兩種方式從索引中刪除文件。「依 ID 刪除」會刪除具有指定 ID 的文件,且僅當在 schema 中定義了 UniqueID 欄位時才能使用。它不適用於子/巢狀文件。「依查詢刪除」會刪除所有符合指定查詢的文件,儘管 commitWithin
會被「依查詢刪除」忽略。單個刪除訊息可以包含多個刪除操作。
<delete>
<id>0002166313</id>
<id>0031745983</id>
<query>subject:sport</query>
<query>publisher:penguin</query>
</delete>
在「依查詢刪除」中使用 Join 查詢解析器時,您應該使用 |
使用 curl 執行更新
您可以使用 curl
工具執行上述任何命令,使用其 --data-binary
選項將 XML 訊息附加到 curl
命令,並產生 HTTP POST 要求。例如
curl https://127.0.0.1:8983/solr/my_collection/update -H "Content-Type: text/xml" --data-binary '
<add>
<doc>
<field name="authors">Patrick Eagar</field>
<field name="subject">Sports</field>
<field name="dd">796.35</field>
<field name="isbn">0002166313</field>
<field name="yearpub">1982</field>
<field name="publisher">Collins</field>
</doc>
</add>'
對於張貼包含在檔案中的 XML 訊息,您可以使用替代形式
curl https://127.0.0.1:8983/solr/my_collection/update -H "Content-Type: text/xml" --data-binary @myfile.xml
上述方法運作良好,但使用 --data-binary
選項會導致 curl
在將整個 myfile.xml
張貼到伺服器之前將其載入記憶體中。在處理多 GB 檔案時,這可能會產生問題。這個替代的 curl
命令執行等效的操作,但 curl
的記憶體使用量最少
curl https://127.0.0.1:8983/solr/my_collection/update -H "Content-Type: text/xml" -T "myfile.xml" -X POST
如果已在 solrconfig.xml
的 requestParsers
元素中啟用,則也可以使用 HTTP GET 命令傳送簡短的要求,並對要求進行 URL 編碼,如下所示。請注意 "<" 和 ">" 的逸出
curl https://127.0.0.1:8983/solr/my_collection/update?stream.body=%3Ccommit/%3E&wt=xml
來自 Solr 的回應會採用此處顯示的形式
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">127</int>
</lst>
</response>
如果發生失敗,status 欄位將為非零值。
使用 XSLT 轉換 XML 索引更新
指令碼模組提供單獨的 XSLT 更新請求處理程式,允許您透過使用 <tr>
參數來應用 XSL 轉換,索引任何任意 XML。您必須在您的 configset 的 conf/xslt
目錄中具有一個 XSLT 樣式表,該樣式表可以將傳入的資料轉換為預期的 <add><doc/></add>
格式,並使用 tr
參數來指定該樣式表的名稱。
您需要先啟用 指令碼模組,才能使用此功能。
XSLT 設定
以下範例來自 Solr 發行版中的 sample_techproducts_configs
configset,顯示如何設定 XSLT 更新請求處理程式。
<!--
Changes to XSLT transforms are taken into account
every xsltCacheLifetimeSeconds at most.
-->
<requestHandler name="/update/xslt"
class="solr.scripting.xslt.XSLTUpdateRequestHandler">
<int name="xsltCacheLifetimeSeconds">5</int>
</requestHandler>
xsltCacheLifetimeSeconds
的值為 5 對於開發來說是不錯的,可以快速查看 XSLT 的變更。對於生產環境,您可能需要更高的值。
XSLT 更新範例
以下是 sample_techproducts_configs/conf/xslt/updateXml.xsl
XSL 檔案,用於將標準 Solr XML 輸出轉換為 Solr 預期的 <add><doc/></add>
格式
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output media-type="text/xml" method="xml" indent="yes"/>
<xsl:template match='/'>
<add>
<xsl:apply-templates select="response/result/doc"/>
</add>
</xsl:template>
<!-- Ignore score (makes no sense to index) -->
<xsl:template match="doc/*[@name='score']" priority="100"></xsl:template>
<xsl:template match="doc">
<xsl:variable name="pos" select="position()"/>
<doc>
<xsl:apply-templates>
<xsl:with-param name="pos"><xsl:value-of select="$pos"/></xsl:with-param>
</xsl:apply-templates>
</doc>
</xsl:template>
<!-- Flatten arrays to duplicate field lines -->
<xsl:template match="doc/arr" priority="100">
<xsl:variable name="fn" select="@name"/>
<xsl:for-each select="*">
<xsl:element name="field">
<xsl:attribute name="name"><xsl:value-of select="$fn"/></xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template match="doc/*">
<xsl:variable name="fn" select="@name"/>
<xsl:element name="field">
<xsl:attribute name="name"><xsl:value-of select="$fn"/></xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>
此樣式表會將 Solr 的 XML 搜尋結果格式轉換為 Solr 的更新 XML 語法。一個範例用法是將 Solr 1.3 索引(沒有 CSV 回應寫入器)複製為可以索引到另一個 Solr 檔案的格式(假設所有欄位都已儲存)
$ curl -o standard_solr_xml_format.xml "https://127.0.0.1:8983/solr/techproducts/select?q=ipod&fl=id,cat,name,popularity,price,score&wt=xml"
$ curl -X POST -H "Content-Type: text/xml" -d @standard_solr_xml_format.xml "https://127.0.0.1:8983/solr/techproducts/update/xslt?commit=true&tr=updateXml.xsl"
您可以使用 回應寫入器 XSLT 範例中的 tr 參數查看相反的匯出/匯入週期。 |
JSON 格式的索引更新
Solr 可以接受符合已定義結構的 JSON,也可以接受任意 JSON 格式的文件。如果傳送任意格式化的 JSON,則需要隨更新請求傳送一些其他參數,這些參數在轉換和索引自訂 JSON一節中說明。
Solr 樣式 JSON
可以使用 Content-Type: application/json
或 Content-Type: text/json
將 JSON 格式的更新請求傳送到 Solr 的 /update
處理程式。
JSON 格式的更新可以採用 3 種基本形式,在下面會詳細說明
新增單個 JSON 文件
透過 JSON 新增文件的最簡單方法是使用 /update/json/docs
路徑,將每個文件單獨作為 JSON 物件傳送
curl -X POST -H 'Content-Type: application/json' 'https://127.0.0.1:8983/solr/my_collection/update/json/docs' --data-binary '
{
"id": "1",
"title": "Doc 1"
}'
新增多個 JSON 文件
可以透過 JSON 物件的 JSON 陣列一次新增多個文件,其中每個物件代表一個文件
curl -X POST -H 'Content-Type: application/json' 'https://127.0.0.1:8983/solr/my_collection/update' --data-binary '
[
{
"id": "1",
"title": "Doc 1"
},
{
"id": "2",
"title": "Doc 2"
}
]'
範例 JSON 檔案位於 example/exampledocs/books.json
,其中包含您可以新增到 Solr 「techproducts」範例的物件陣列
curl 'https://127.0.0.1:8983/solr/techproducts/update?commit=true' --data-binary @example/exampledocs/books.json -H 'Content-type:application/json'
傳送 JSON 更新指令
一般來說,JSON 更新語法支援 XML 更新處理程式支援的所有更新指令,透過簡單的對應。一個訊息中可以包含多個命令,新增和刪除文件
curl -X POST -H 'Content-Type: application/json' 'https://127.0.0.1:8983/solr/my_collection/update' --data-binary '
{
"add": {
"doc": {
"id": "DOC1",
"my_field": 2.3,
"my_multivalued_field": [ "aaa", "bbb" ] (1)
}
},
"add": {
"commitWithin": 5000, (2)
"overwrite": false, (3)
"doc": {
"f1": "v1", (4)
"f1": "v2"
}
},
"commit": {},
"optimize": { "waitSearcher":false },
"delete": { "id":"ID" }, (5)
"delete": { "query":"QUERY" } (6)
}'
1 | 可以使用陣列表示多值欄位 |
2 | 在 5 秒內提交此文件 |
3 | 不要檢查是否存在具有相同 uniqueKey 的文件 |
4 | 可以使用重複的鍵表示多值欄位 |
5 | 依 ID 刪除 (uniqueKey 欄位) |
6 | 依查詢刪除 |
與其他更新處理程式一樣,可以在 URL 中指定 commit
、commitWithin
、optimize
和 overwrite
等參數,而不是在訊息的主體中指定。
JSON 更新格式允許簡單的依 ID 刪除。delete
的值可以是一個陣列,其中包含要刪除的零個或多個特定文件 ID (不是範圍)。例如,單個文件
{ "delete":"myid" }
或文件 ID 清單
{ "delete":["id1","id2"] }
注意:依 ID 刪除不適用於子/巢狀文件。
您也可以為每個「delete」指定 _version_
{
"delete":"id":50,
"_version_":12345
}
您也可以在更新請求的主體中指定刪除的版本。
JSON 更新便利路徑
除了 /update
處理程式外,Solr 中預設還提供了一些其他特定於 JSON 的請求處理程式路徑,這些路徑會隱式覆寫某些請求參數的行為
路徑 | 預設參數 |
---|---|
|
|
|
|
/update/json
路徑對於從應用程式傳送 JSON 格式的更新指令的用戶端可能很有用,因為設定 Content-Type 很困難,而 /update/json/docs
路徑對於始終想要傳送文件(單獨或以清單形式)而無需擔心完整 JSON 命令語法的用戶端來說,可能特別方便。
自訂 JSON 文件
Solr 可以支援自訂 JSON。這在轉換和索引自訂 JSON一節中介紹。
CSV 格式的索引更新
可以使用 Content-Type: application/csv
或 Content-Type: text/csv
將 CSV 格式的更新請求傳送到 Solr 的 /update
處理程式。
範例 CSV 檔案位於 example/exampledocs/books.csv
,您可以使用它將一些文件新增到 Solr 「techproducts」範例
curl 'https://127.0.0.1:8983/solr/my_collection/update?commit=true' --data-binary @example/exampledocs/books.csv -H 'Content-type:application/csv'
CSV 更新參數
CSV 處理器允許在 URL 中以以下格式指定多個參數:f.parameter.optional_fieldname=value
。
下表描述了更新處理器的參數。
separator
-
選用
預設值:
,
用作欄位分隔符號的字元。此參數為全域性;若要針對每個欄位使用,請參閱
split
參數。範例:
separator=%09
trim
-
選用
預設值:
false
如果為
true
,則移除值的前導和尾隨空白。此參數可以是全域性或針對每個欄位設定。範例:
f.isbn.trim=true
或trim=false
header
-
選用
預設值:
true
如果輸入的第一行包含欄位名稱,則設定為
true
。如果缺少fieldnames
參數,將會使用這些欄位名稱。此參數為全域性。 fieldnames
-
選用
預設值:無
新增文件時要使用的欄位名稱列表,以逗號分隔。此參數為全域性。
範例:
fieldnames=isbn,price,title
literal.field_name
-
選用
預設值:無
指定欄位名稱的文字值。此參數為全域性。
範例:
literal.color=red
skip
-
選用
預設值:無
要略過的欄位名稱列表,以逗號分隔。此參數為全域性。
範例:
skip=uninteresting,shoesize
skipLines
-
選用
預設值:
0
在 CSV 資料開始之前,要捨棄輸入串流中的行數,包括標頭(如果存在)。此參數為全域性。
範例:
skipLines=5
encapsulator
-
選用
預設值:無
選擇性用於包圍值的字元,以保留諸如 CSV 分隔符號或空白之類的字元。這種標準 CSV 格式透過將封裝符號加倍,來處理封裝值中出現的封裝符號本身。
此參數為全域性;若要針對每個欄位使用,請參閱
split
。範例:
encapsulator="
escape
-
選用
預設值:無
用於跳脫 CSV 分隔符號或其他保留字元的字元。如果指定了跳脫字元,則除非也明確指定,否則不會使用封裝符號,因為大多數格式使用封裝或跳脫,而不是兩者都使用。
範例:
escape=\
keepEmpty
-
選用
預設值:
false
保留並索引零長度(空)欄位。此參數可以是全域性或針對每個欄位設定。
範例:
f.price.keepEmpty=true
map
-
選用
預設值:無
將一個值對應到另一個值。格式為
map=value:replacement
(可以為空)。此參數可以是全域性或針對每個欄位設定。範例:
map=left:right
或f.subject.map=history:bunk
split
-
選用
預設值:無
如果為
true
,則使用單獨的剖析器將欄位分割為多個值。此參數是針對每個欄位使用的,例如f.FIELD_NAME_GOES_HERE.split=true
。 overwrite
-
選用
預設值:
true
如果為
true
,則根據 Solr 綱要中宣告的 uniqueKey 欄位,檢查並覆寫重複的文件。如果您知道要索引的文件不包含任何重複項,則將此值設定為false
可以顯著加快速度。此參數為全域性。
commit
-
選用
預設值:無
在擷取資料後發出提交。此參數為全域性。
commitWithin
-
選用
預設值:無
在指定的毫秒數內新增文件。此參數為全域性。
範例:
commitWithin=10000
rowid
-
選用
預設值:無
將
rowid
(行號)對應到參數值指定的欄位,例如,如果您的 CSV 沒有唯一索引鍵,並且您想要使用行 ID 作為唯一索引鍵。此參數為全域性。範例:
rowid=id
rowidOffset
-
選用
預設值:
0
將給定的偏移量(作為整數)新增到
rowid
,然後再將其新增到文件中。此參數為全域性。範例:
rowidOffset=10
索引索引標籤分隔的檔案
用於索引 CSV 文件的相同功能,也可以輕鬆用於索引索引標籤分隔的檔案(TSV 檔案),甚至可以處理反斜線跳脫,而不是 CSV 封裝。
例如,可以使用以下方式將 MySQL 資料表轉儲到索引標籤分隔的檔案:
SELECT * INTO OUTFILE '/tmp/result.txt' FROM mytable;
然後可以透過將 separator
設定為索引標籤 (%09) 並將 escape
設定為反斜線 (%5c),將此檔案匯入 Solr。
curl 'https://127.0.0.1:8983/solr/my_collection/update/csv?commit=true&separator=%09&escape=%5c' --data-binary @/tmp/result.txt