Solr使用索引處理程序上傳數(shù)據(jù)

2018-11-21 15:07 更新

索引處理程序是一種請(qǐng)求處理程序,旨在添加、刪除和更新文件到索引。除了使用 Tika 導(dǎo)入豐富文檔的插件或使用數(shù)據(jù)導(dǎo)入處理程序的結(jié)構(gòu)化數(shù)據(jù)源外,Solr 本身還支持以 XML、CSV 和 JSON 中的結(jié)構(gòu)化文檔索引。

建議配置和使用請(qǐng)求處理程序的方法是使用基于路徑的名稱映射到請(qǐng)求 url 中的路徑。但是,如果正確配置了 requestDispatcher,則也可以使用 qt(查詢類型)參數(shù)指定請(qǐng)求處理程序??梢允褂枚鄠€(gè)名稱來訪問相同的處理程序,如果您希望指定不同的默認(rèn)選項(xiàng)集,這可能很有用。

一個(gè)統(tǒng)一的更新請(qǐng)求處理程序支持 XML、CSV、JSON 和 javabin 更新請(qǐng)求,并根據(jù) ContentStream 的內(nèi)容類型委派給適當(dāng)?shù)?ContentStreamLoader。

UpdateRequestHandler 配置

默認(rèn)配置文件具有默認(rèn)配置的更新請(qǐng)求處理程序。

<requestHandler name="/update" class="solr.UpdateRequestHandler" />

XML 格式化索引更新

索引更新命令可以使用 Content-type: application/xml 或者 Content-type: text/xml 作為 XML 消息發(fā)送到更新處理程序。

添加文檔

由更新處理程序識(shí)別的用于添加文檔的 XML 架構(gòu)非常簡(jiǎn)單:

  • <add> 元素引入了一個(gè)要添加的文檔。
  • <doc> 元素引入了組成文檔的字段。
  • <field> 元素顯示具有特定領(lǐng)域的內(nèi)容。

例如:

<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>

add 命令支持一些可以指定的可選屬性。

commitWithin

在指定的毫秒數(shù)內(nèi)添加文檔。

overwrite

默認(rèn)是 true。指示是否應(yīng)檢查唯一鍵約束以覆蓋同一文檔的以前版本(請(qǐng)參見下文)。

如果文檔架構(gòu)定義了唯一的鍵,那么默認(rèn)情況下,添加文檔的 /update 操作將使用相同的唯一鍵覆蓋(即替換)索引中的任何文檔。如果沒有定義唯一的鍵,索引性能會(huì)更快一些,因?yàn)椴恍枰獙?duì)現(xiàn)有文檔進(jìn)行任何檢查來替換。

如果您有一個(gè)唯一的關(guān)鍵字段,但您確信您可以安全地繞過唯一性檢查(例如,在批處理中生成索引,并且索引代碼保證它從不多次添加同一文檔),您可以指定overwrite="false" 選項(xiàng)當(dāng)您添加您的文檔時(shí)。

XML 更新命令

在更新期間提交和優(yōu)化

該 <commit> 操作將自從上次提交后加載的所有文檔寫入磁盤上的一個(gè)或多個(gè)段文件。在提交之前,新索引的內(nèi)容對(duì)于搜索是不可見的。提交操作將打開一個(gè)新的搜索器,并觸發(fā)已配置的任何事件偵聽器。

可以使用 <commit/> 消息顯式發(fā)出提交,也可以在 solrconfig. xml 中觸發(fā) <autocommit> 參數(shù)。

該 <optimize> 操作請(qǐng)求 Solr 合并內(nèi)部數(shù)據(jù)結(jié)構(gòu)以提高搜索性能。對(duì)于大型索引,優(yōu)化需要一些時(shí)間才能完成,但是通過將許多小段文件合并為一個(gè)更大的文件,搜索性能將會(huì)提高。如果您使用 Solr 的復(fù)制機(jī)制在多個(gè)系統(tǒng)上分發(fā)搜索,請(qǐng)注意,在進(jìn)行優(yōu)化之后,需要傳輸一個(gè)完整的索引。相比之下,提交后的轉(zhuǎn)移通常要小得多。

在 <commit> 和 <optimize> 元素中接受這些可選屬性:

waitSearcher

默認(rèn)是 true。阻塞,直到打開新的搜索器并注冊(cè)為主查詢搜索器,使更改可見。

expungeDeletes

(只提交)默認(rèn)是 false。合并超過10%已刪除文檔的細(xì)分受眾群,并在此過程中將其刪除。

maxSegments

(僅限優(yōu)化)默認(rèn)是1。將分段合并到不超過此段數(shù)量。

以下是使用 <commit> 和 <optimize> 可選屬性的示例:

<commit waitSearcher="false"/>
<commit waitSearcher="false" expungeDeletes="true"/>
<optimize waitSearcher="false"/>

刪除操作

文件可以通過兩種方式從索引中刪除。“按 ID 刪除”刪除具有指定 ID 的文檔,只有在架構(gòu)中定義了 UniqueID 字段時(shí)才能使用?!鞍床樵儎h除”會(huì)刪除與指定查詢匹配的所有文檔,但 commitWithin 對(duì)于按查詢刪除而言將被忽略。單個(gè)刪除消息可以包含多個(gè)刪除操作。

<delete>
  <id>0002166313</id>
  <id>0031745983</id>
  <query>subject:sport</query>
  <query>publisher:penguin</query>
</delete>
注意:在 Delete By Query(按查詢刪除)中使用 Join 查詢解析器時(shí),應(yīng)該使用值為 “none” 的 score 參數(shù)來避免 ClassCastException。有關(guān) score 參數(shù)的更多詳細(xì)信息,請(qǐng)參見 Join Query Parser(聯(lián)接查詢分析器)部分。

回滾操作

回滾命令將回滾自上次提交以來對(duì)索引所做的所有添加和刪除操作。它既不調(diào)用任何事件偵聽器也不創(chuàng)建新的搜索器。它的語法很簡(jiǎn)單:<rollback/>。

使用 curl 來執(zhí)行更新

您可以使用 curl 實(shí)用程序執(zhí)行上述任何命令,使用其 --data-binary 選項(xiàng)將 XML 消息附加到 curl 命令,并生成 HTTP POST 請(qǐng)求。例如:

curl http://localhost: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>'

要發(fā)布文件中包含的 XML 消息,可以使用其他形式:

curl http://localhost:8983/solr/my_collection/update -H "Content-Type: text/xml" --data-binary @myfile.xml

也可以使用 HTTP GET 命令發(fā)送短請(qǐng)求(如果在 SolrConfig 元素中的 RequestDispatcher 中啟用),請(qǐng)對(duì) URL 進(jìn)行編碼,如下所示。注意"<" and ">"的轉(zhuǎn)義:

curl http://localhost:8983/solr/my_collection/update?stream.body=%3Ccommit/%3E

Solr 的回應(yīng)采取如下所示的形式:

<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">127</int>
  </lst>
</response>

在失敗的情況下,狀態(tài)字段將是非零的。

使用 XSLT 轉(zhuǎn)換 XML 索引更新

UpdateRequestHandler 允許您使用 <tr> 參數(shù)來應(yīng)用 XSL 轉(zhuǎn)換來索引任意 XML。您必須在配置集的 conf/xslt 目錄中有一個(gè) XSLT 樣式表,可以將傳入的數(shù)據(jù)轉(zhuǎn)換為預(yù)期的 <add><doc/></add> 格式,并使用 tr 參數(shù)指定該樣式表的名稱。

下面是一個(gè) XSLT 樣式表示例:

<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 搜索結(jié)果格式轉(zhuǎn)換為 Solr 的更新 XML 語法。一個(gè)示例用法是將 Solr 1.3 索引(沒有 CSV 響應(yīng)編寫器)復(fù)制為可以索引到另一個(gè) Solr 文件中的格式(前提是所有字段都存儲(chǔ)):

http://localhost:8983/solr/my_collection/select?q=*:*&wt=xslt&tr=updateXml.xsl&rows=1000

XsltUpdateRequestHandler 更新時(shí)也可以使用樣式表來轉(zhuǎn)換索引:

curl "http://localhost:8983/solr/my_collection/update?commit=true&tr=updateXml.xsl" -H "Content-Type: text/xml" --data-binary @myexporteddata.xml

JSON 格式化索引更新

Solr 可以接受符合定義結(jié)構(gòu)的 JSON,或者可以接受任意的 JSON 格式的文檔。如果發(fā)送任意格式的 JSON,則需要使用更新請(qǐng)求發(fā)送一些其他參數(shù),如下面的“自定義JSON 轉(zhuǎn)換和索引”部分所述。

Solr 風(fēng)格的 JSON

JSON 格式的更新請(qǐng)求可以使用 Content-Type: application/json 或 Content-Type: text/json 發(fā)送到 Solr 的 /update 處理程序。

JSON 格式的更新可以采取 3 種基本形式,下面進(jìn)行深入的描述:

  • 要添加的單個(gè)文檔,表示為頂級(jí) JSON 對(duì)象。為了區(qū)分這一點(diǎn)與一組命令,json.command=false 請(qǐng)求參數(shù)是必需的。
  • 要添加的文檔列表,表示為包含每個(gè)文檔的 JSON 對(duì)象的頂級(jí) JSON 數(shù)組。
  • 一系列更新命令,表示為頂級(jí) JSON 對(duì)象(又名:Map)。

添加一個(gè) JSON 文檔

通過 JSON 添加文檔的最簡(jiǎn)單方法是使用以下 /update/json/docs 路徑將每個(gè)文檔分別作為 JSON 對(duì)象單獨(dú)發(fā)送:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_collection/update/json/docs' --data-binary '
{
  "id": "1",
  "title": "Doc 1"
}'

添加多個(gè) JSON 文檔

通過 JSON 一次添加多個(gè)文檔可以通過 JSON 對(duì)象的 JSON 數(shù)組完成,其中每個(gè)對(duì)象都代表一個(gè)文檔:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_collection/update' --data-binary '
[
  {
    "id": "1",
    "title": "Doc 1"
  },
  {
    "id": "2",
    "title": "Doc 2"
  }
]'

一個(gè)示例 JSON 文件提供的 example/exampledocs/books.json 并包含可添加到 Solr techproducts 示例的對(duì)象數(shù)組:

curl 'http://localhost:8983/solr/techproducts/update?commit=true' --data-binary @example/exampledocs/books.json -H 'Content-type:application/json'

發(fā)送 JSON 更新命令

發(fā)送 JSON 更新命令通常, JSON 更新語法通過簡(jiǎn)單的映射支持 XML 更新處理程序支持的所有更新命令。多條命令、添加和刪除文檔可能包含在一條消息中:

curl -X POST -H 'Content-Type: application/json' 'http://localhost: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】
}'

以下解釋對(duì)應(yīng)于上述代碼:

  1. 可以對(duì)多值字段使用數(shù)組
  2. 在5秒內(nèi)提交此文檔
  3. 不要使用相同的 uniqueKey 檢查現(xiàn)有文檔
  4. 可以對(duì)多值字段使用重復(fù)鍵
  5. 按 ID 刪除 (uniqueKey 字段)
  6. 按查詢刪除

與其他更新處理程序一樣,可以在 URL 而不是消息正文中指定諸如 commit、commitWithin、optimize 和 overwrite 等參數(shù)。

JSON 更新格式允許簡(jiǎn)單的刪除 ID。delete 的值可以是一個(gè)數(shù)組,其中包含零個(gè)或多個(gè)特定文檔 ID(不是范圍)的要?jiǎng)h除的列表。例如,單個(gè)文檔:

{ "delete":"myid" }

或文檔 ID 的列表:

{ "delete":["id1","id2"] }

“delete”的值可以是包含要?jiǎng)h除的零個(gè)或多個(gè) ID 的列表的數(shù)組。這不是一個(gè)范圍(開始和結(jié)束)。

您也可以使用每個(gè)“delete” 指定  _version_ :

{
  "delete":"id":50,
  "_version_":12345
}

您也可以在更新請(qǐng)求的主體中指定刪除的版本。

JSON 更新便利路徑

除了 /update 處理程序之外,Solr 中默認(rèn)還有一些額外的 JSON 特定的請(qǐng)求處理程序路徑,它隱式覆蓋了一些請(qǐng)求參數(shù)的行為:

路徑 默認(rèn)參數(shù)

/update/json

stream.contentType=application/json

/update/json/docs

stream.contentType=application/json

json.command=false

該 /update/json 路徑對(duì)于從設(shè)置 Content-Type 的應(yīng)用程序中發(fā)送 JSON 格式的更新命令的客戶端來說非常有用,因?yàn)樵O(shè)置 Content-Type 的應(yīng)用程序證明是困難的,而 /update/json/docs 路徑對(duì)于總是希望單獨(dú)發(fā)送或作為列表發(fā)送文檔的客戶端而言,可能是特別方便的,無需擔(dān)心完整的 JSON 命令語法。

自定義 JSON 文檔

Solr 可以支持自定義的 JSON。這在 “自定義 JSON 轉(zhuǎn)換和索引” 部分中進(jìn)行了介紹。

CSV 格式索引更新

CSV 格式的更新請(qǐng)求可以使用 Content-Type: application/csv 或 Content-Type: text/csv 發(fā)送到 Solr 的 /update 處理程序。

一個(gè)示例 CSV 文件提供了 example/exampledocs/books.csv,您可以使用它將一些文檔添加到 Solr techproducts 示例中:

curl 'http://localhost:8983/solr/my_collection/update?commit=true' --data-binary @example/exampledocs/books.csv -H 'Content-type:application/csv'

CSV 更新參數(shù)

該 CSV 處理程序允許在表單中的 URL 中的 f.parameter.optional_fieldname=value 指定許多參數(shù)。

下表介紹了更新處理程序的參數(shù)。

separator

用作字段分隔符的字符;默認(rèn)是“,”。這個(gè)參數(shù)是全局的;對(duì)于每個(gè)字段的使用情況,請(qǐng)參閱split參數(shù)。

例:separator=%09

trim

如果true從值中刪除前導(dǎo)和尾隨空白。默認(rèn)是false。此參數(shù)可以是全局或每個(gè)字段。

例子:f.isbn.trim=truetrim=false

header

如果輸入的第一行包含字段名稱,則設(shè)置為 true;如果fieldnames參數(shù)不存在,將使用這些參數(shù)。這個(gè)參數(shù)是全局的。

fieldnames

添加文檔時(shí)使用逗號(hào)分隔的字段名稱列表。這個(gè)參數(shù)是全局的。

例:fieldnames=isbn,price,title

literal.field_name

指定字段名稱的文字值。這個(gè)參數(shù)是全局的。

例:literal.color=red

skip

逗號(hào)分隔的字段名稱列表跳過。這個(gè)參數(shù)是全局的。

例:skip=uninteresting,shoesize

skipLines

在 CSV 數(shù)據(jù)開始之前在輸入流中放棄的行數(shù),包括標(biāo)題(如果存在)。默認(rèn) = 0。這個(gè)參數(shù)是全局的。

例:skipLines=5

encapsulator

字符可選用于包圍值以保留字符(如 CSV 分隔符或空格)。這個(gè)標(biāo)準(zhǔn)的 CSV 格式通過加倍封裝器來處理出現(xiàn)在封裝值中的封裝器本身。

這個(gè)參數(shù)是全局的;有關(guān)每個(gè)字段的使用情況,請(qǐng)參閱split。

例:encapsulator="

escape

用于轉(zhuǎn)義 CSV 分隔符或其他保留字符的字符。如果指定了轉(zhuǎn)義,則除非明確指定,否則不使用封裝器,因?yàn)榇蠖鄶?shù)格式使用封裝或轉(zhuǎn)義,而不是兩種方式。

      例: escape=\

keepEmpty

保留和索引零長(zhǎng)度(空)字段。默認(rèn)是false。此參數(shù)可以是全局或每個(gè)字段。

例:f.price.keepEmpty=true

map

將一個(gè)值映射到另一個(gè)值。格式是 value:replacement(可以是空的)。此參數(shù)可以是全局或每個(gè)字段。

例如:map=left:rightf.subject.map=history:bunk

split

如果true通過單獨(dú)的解析器將字段分成多個(gè)值。該參數(shù)在每個(gè)字段的基礎(chǔ)上使用。

overwrite

如果true(默認(rèn)),根據(jù) Solr 模式中聲明的 uniqueKey 字段檢查并覆蓋重復(fù)的文檔。如果您知道索引的文檔不包含任何重復(fù)內(nèi)容,那么您可能會(huì)看到相當(dāng)快的速度false。

這個(gè)參數(shù)是全局的。

commit

數(shù)據(jù)攝取后發(fā)出提交。這個(gè)參數(shù)是全局的。

commitWithin

在指定的毫秒數(shù)內(nèi)添加文檔。這個(gè)參數(shù)是全局的。

例:commitWithin=10000

rowid

rowid(行號(hào))映射到由參數(shù)的值指定的字段,例如,如果您的 CSV 沒有唯一鍵,并且您想要使用行標(biāo)識(shí)。這個(gè)參數(shù)是全局的。

例:rowid=id

rowidOffset

將給定的偏移量(作為整數(shù))rowid添加到文檔之前。默認(rèn)是0。這個(gè)參數(shù)是全局的。

例:rowidOffset=10

索引制表符分隔的文件

用于索引 CSV 文檔的相同功能也可以輕松用于索引制表符分隔的文件(TSV 文件),甚至可以處理反斜杠轉(zhuǎn)義而不是 CSV 封裝。

例如,可以使用以下命令將 MySQL 表轉(zhuǎn)儲(chǔ)到制表符分隔的文件中:

SELECT * INTO OUTFILE '/tmp/result.txt' FROM mytable;

然后可以通過將分隔符設(shè)置為 tab(%09)和 轉(zhuǎn)義符(%5c)將該文件導(dǎo)入到 Solr 。

curl 'http://localhost:8983/solr/my_collection/update/csv?commit=true&separator=%09&escape=%5c' --data-binary @/tmp/result.txt

CSV 更新便利路徑

除了 /update 處理程序之外,Solr 中默認(rèn)還有一個(gè)額外的 CSV 特定請(qǐng)求處理程序路徑,它隱式地覆蓋了一些請(qǐng)求參數(shù)的行為:

路徑 默認(rèn)參數(shù)

/update/csv

stream.contentType=application/csv

該 /update/csv 路徑對(duì)于客戶端發(fā)送 CSV 格式的更新命令來說很有用,這些應(yīng)用程序設(shè)置 Content-Type 非常困難。

嵌套的子文檔

Solr將嵌套的文檔嵌套在塊中,以將包含其他文檔的文檔(比如一個(gè) blog post 父文檔和注釋作為子文檔)或作為父文檔和大小、顏色或其他變體的子文檔作為子文檔來建模文檔。在查詢時(shí),塊聯(lián)接查詢解析器( Block Join Query Parsers)可以搜索這些關(guān)系。就性能而言,索引文檔之間的關(guān)系可能比試圖僅在查詢時(shí)進(jìn)行連接更有效率,因?yàn)殛P(guān)系已經(jīng)存儲(chǔ)在索引中并且不需要被計(jì)算。

嵌套文檔可以通過 XML 或 JSON 數(shù)據(jù)語法(或使用 SolrJ)進(jìn)行索引- 但是不管語法如何,您都必須包含一個(gè)將父文檔標(biāo)識(shí)為父項(xiàng)的字段;它可以是適合這個(gè)目的的任何字段,它將被用作塊連接查詢解析器的輸入。

為了支持嵌套文檔,架構(gòu)必須包含 indexed/non-stored 字段_root_。無論繼承深度如何,該字段的值都會(huì)自動(dòng)填充,并且與塊中的所有文檔相同。

XML 示例

例如,這里有兩個(gè)文件及其子文件:

<add>
  <doc>
  <field name="id">1</field>
  <field name="title">Solr adds block join support</field>
  <field name="content_type">parentDocument</field>
    <doc>
      <field name="id">2</field>
      <field name="comments">SolrCloud supports it too!</field>
    </doc>
  </doc>
  <doc>
    <field name="id">3</field>
    <field name="title">New Lucene and Solr release is out</field>
    <field name="content_type">parentDocument</field>
    <doc>
      <field name="id">4</field>
      <field name="comments">Lots of new features</field>
    </doc>
  </doc>
</add>

在這個(gè)例子中,我們使用字段 content_type 索引父文檔,它具有值 “parentDocument”。我們也可以使用一個(gè)布爾型的字段,比如 isParent 值為 “true”,或者其他類似的方法。

JSON 示例

這個(gè)例子相當(dāng)于上面的 XML 例子,請(qǐng)注意特殊的 _childDocuments_ 鍵需要指示 JSON 中的嵌套文檔。

[
  {
    "id": "1",
    "title": "Solr adds block join support",
    "content_type": "parentDocument",
    "_childDocuments_": [
      {
        "id": "2",
        "comments": "SolrCloud supports it too!"
      }
    ]
  },
  {
    "id": "3",
    "title": "New Lucene and Solr release is out",
    "content_type": "parentDocument",
    "_childDocuments_": [
      {
        "id": "4",
        "comments": "Lots of new features"
      }
    ]
  }
]

注意:對(duì)嵌套文檔進(jìn)行索引的一個(gè)限制是,在需要進(jìn)行任何更改時(shí),必須將整個(gè)父子文檔塊一起更新。換言之,即使更改了單個(gè)子文檔或父文檔,也必須將整個(gè)父子文檔塊編入索引。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)