Solr無架構(gòu)模式

2018-11-13 16:10 更新
無架構(gòu)模式是一組 Solr 功能,它們一起使用時,用戶只需簡單地對示例數(shù)據(jù)進(jìn)行索引就可以快速構(gòu)建有效的架構(gòu),而無需手動編輯模式。

這些 Solr 功能都是通過 solrconfig.xml 方式控制的:

  1. 托管架構(gòu):在運行時通過 Solr API 進(jìn)行架構(gòu)修改,這需要使用支持這些更改的 schemaFactory。有關(guān)更多詳細(xì)信息,請參閱 SolrConfig 中的 "架構(gòu)工廠定義" 部分。
  2. 字段值類猜測:以前看不到的字段是通過一組級聯(lián)的價值分析器來運行的,它們猜測 Java 類的字段值 - 布爾型、整數(shù)型、長整型、浮點型、雙精度型和日期型的解析器當(dāng)前可用。
  3. 基于字段值類(es)的自動模式字段添加:基于字段值 Java 類(字段值映射到架構(gòu)字段類型),將先前看不到的字段添加到模式中。 - 請參閱 Solr 字段類型。

使用無架構(gòu)示例

無架構(gòu)模式的三個特性是在 Solr 分配的 _default 配置集中預(yù)先配置的。要使用這些配置啟動 Solr 的示例實例,請運行以下命令:

bin/solr start -e schemaless

這將啟動一個 Solr 的服務(wù)器,并自動創(chuàng)建一個集合(名為 “gettingstarted 只包含三個初始架構(gòu)字段”):id、_version_ 和 _text_。

你可以使用 /schema/fields Schema API 來確認(rèn):curl http://localhost:8983/solr/gettingstarted/schema/fields 輸出:

{
  "responseHeader":{
    "status":0,
    "QTime":1},
  "fields":[{
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"long",
      "indexed":true,
      "stored":true},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true,
      "uniqueKey":true}]}

配置無看過模式

如上所述,有三種配置元素需要在無架構(gòu)模式下使用 Solr。在 _defaultSolr 包含的配置集中,這些已經(jīng)配置好了。但是,如果您想自己實現(xiàn)無架構(gòu),則應(yīng)進(jìn)行以下更改。

啟用托管架構(gòu)

如 SolrConfig 中的 Schema Factory Definition 一節(jié)所述,除非您的配置指定 ClassicIndexSchemaFactory 應(yīng)該使用 Managed Schema 支持,否則默認(rèn)情況下啟用 Managed Schema 支持。

您可以通過添加顯式 <schemaFactory/> (如下所示) 來配置 ManagedIndexSchemaFactory (并控制所使用的資源文件,或禁用將來的修改),請參閱 SolrConfig中的架構(gòu)工廠定義以獲取有關(guān)可用選項的更多詳細(xì)信息。

<schemaFactory class="ManagedIndexSchemaFactory">
  <bool name="mutable">true</bool>
  <str name="managedSchemaResourceName">managed-schema</str>
</schemaFactory>

啟用字段類猜測

在 Solr 中,UpdateRequestProcessorChain 定義了一系列插件,這些插件在索引之前或索引時應(yīng)用于文檔。

Solr 的無架構(gòu)模式的字段猜測方面使用專門定義的允許 Solr 猜測字段類型的 UpdateRequestProcessorChain。您還可以定義要使用的默認(rèn)字段類型類。

首先,您應(yīng)該如下定義它(更新處理器工廠文檔,請參閱下面的 javadoc 鏈接):

<updateProcessor class="solr.UUIDUpdateProcessorFactory" name="uuid"/>
  <updateProcessor class="solr.RemoveBlankFieldUpdateProcessorFactory" name="remove-blank"/>
  <updateProcessor class="solr.FieldNameMutatingUpdateProcessorFactory" name="field-name-mutating"> 【1】
    <str name="pattern">[^\w-\.]</str>
    <str name="replacement">_</str>
  </updateProcessor>
  <updateProcessor class="solr.ParseBooleanFieldUpdateProcessorFactory" name="parse-boolean"/> 【2】
  <updateProcessor class="solr.ParseLongFieldUpdateProcessorFactory" name="parse-long"/>
  <updateProcessor class="solr.ParseDoubleFieldUpdateProcessorFactory" name="parse-double"/>
  <updateProcessor class="solr.ParseDateFieldUpdateProcessorFactory" name="parse-date">
    <arr name="format">
      <str>yyyy-MM-dd'T'HH:mm:ss.SSSZ</str>
      <str>yyyy-MM-dd'T'HH:mm:ss,SSSZ</str>
      <str>yyyy-MM-dd'T'HH:mm:ss.SSS</str>
      <str>yyyy-MM-dd'T'HH:mm:ss,SSS</str>
      <str>yyyy-MM-dd'T'HH:mm:ssZ</str>
      <str>yyyy-MM-dd'T'HH:mm:ss</str>
      <str>yyyy-MM-dd'T'HH:mmZ</str>
      <str>yyyy-MM-dd'T'HH:mm</str>
      <str>yyyy-MM-dd HH:mm:ss.SSSZ</str>
      <str>yyyy-MM-dd HH:mm:ss,SSSZ</str>
      <str>yyyy-MM-dd HH:mm:ss.SSS</str>
      <str>yyyy-MM-dd HH:mm:ss,SSS</str>
      <str>yyyy-MM-dd HH:mm:ssZ</str>
      <str>yyyy-MM-dd HH:mm:ss</str>
      <str>yyyy-MM-dd HH:mmZ</str>
      <str>yyyy-MM-dd HH:mm</str>
      <str>yyyy-MM-dd</str>
    </arr>
  </updateProcessor>
  <updateProcessor class="solr.AddSchemaFieldsUpdateProcessorFactory" name="add-schema-fields"> 【3】
    <lst name="typeMapping">
      <str name="valueClass">java.lang.String</str> 【4】
      <str name="fieldType">text_general</str>
      <lst name="copyField"> 【5】
        <str name="dest">*_str</str>
        <int name="maxChars">256</int>
      </lst>
      <!-- Use as default mapping instead of defaultFieldType -->
      <bool name="default">true</bool>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.lang.Boolean</str>
      <str name="fieldType">booleans</str>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.util.Date</str>
      <str name="fieldType">pdates</str>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.lang.Long</str> 【6】
      <str name="valueClass">java.lang.Integer</str>
      <str name="fieldType">plongs</str>
    </lst>
    <lst name="typeMapping">
      <str name="valueClass">java.lang.Number</str>
      <str name="fieldType">pdoubles</str>
    </lst>
  </updateProcessor>

  <!-- The update.autoCreateFields property can be turned to false to disable schemaless mode -->
  <updateRequestProcessorChain name="add-unknown-fields-to-the-schema" default="${update.autoCreateFields:true}"
           processor="uuid,remove-blank,field-name-mutating,parse-boolean,parse-long,parse-double,parse-date,add-schema-fields"> 【7】
    <processor class="solr.LogUpdateProcessorFactory"/>
    <processor class="solr.DistributedUpdateProcessorFactory"/>
    <processor class="solr.RunUpdateProcessorFactory"/>
  </updateRequestProcessorChain>

這條鏈上定義了很多東西。我們來看看其中的一些:

  1. 首先,我們使用 FieldNameMutatingUpdateProcessorFactory 來小寫所有字段名稱。注意,這個和每個后續(xù)的<processor>元素包括一個name。這些名稱將在本例末尾的最后一個鏈定義中使用。
  2. 接下來,我們添加幾個更新請求處理器來解析不同的字段類型。注意 ParseDateFieldUpdateProcessorFactory 包括一長串可能的日期的形成,會被解析成有效的 Solr 日期。如果您有一個自定義的日期,您可以將它添加到這個列表中(參見下面的 Javadocs 鏈接以獲得關(guān)于如何實現(xiàn)的信息)。
  3. 一旦字段被解析,我們定義將被分配給這些字段的字段類型。您可以修改任何你想要改變的東西。
  4. 在這個定義中,如果解析步驟決定一個字段中的傳入數(shù)據(jù)是一個字符串,那么我們將把它放到 Solr 中的字段類型為 text_general 的字段中。這個字段類型默認(rèn)允許Solr 在這個字段上查詢。
  5. 在我們添加了 text_general 字段之后,我們還定義了一個復(fù)制字段規(guī)則,它將從新的 text_general 字段復(fù)制所有數(shù)據(jù)到帶有 _str 相同名稱的字段。這是由 Solr 的動態(tài)字段特性完成的。通過用這種方式將復(fù)制字段規(guī)則的目標(biāo)定義為一個動態(tài)字段,您可以控制模式中使用的字段類型。默認(rèn)選擇允許 Solr 在這些字段上進(jìn)行 facet、高亮顯示和排序。
  6. 這是映射規(guī)則的另一個例子。在這種情況下,我們定義當(dāng)字段LongInteger字段解析器中的任何一個識別出字段時,它們應(yīng)該將它們的字段映射到 plongs 字段類型。
  7. 最后,我們添加一個稱為插件列表的鏈定義。當(dāng)我們定義這些插件時,它們都是由我們給它們的名字命名的。我們還可以向鏈中添加其他處理器,如下所示。注意,我們還為整個鏈提供了一個 name (“添加未知字段到模式”)。我們將在下一節(jié)中使用這個名字來指定我們的更新請求處理程序應(yīng)該使用這個鏈定義。

此鏈定義將為要從相應(yīng)的文本字段創(chuàng)建的字符串字段建立多個復(fù)制字段規(guī)則。如果您的數(shù)據(jù)導(dǎo)致您最終使用了大量的復(fù)制字段規(guī)則,則索引可能會明顯減慢,并且索引大小將會更大。為了控制這些問題,建議您查看創(chuàng)建的復(fù)制字段規(guī)則,并刪除不需要的 faceting、排序、突出顯示等。

如果您對這個鏈中使用的類的更多的信息感興趣,下面是上面提到的更新處理器工廠的 Javadocs 的鏈接:

設(shè)置默認(rèn)的 UpdateRequestProcessorChain

一旦定義了 UpdateRequestProcessorChain,你必須指示你的 UpdateRequestHandlers 在處理索引更新時使用它(即添加、刪除、替換文檔)。

有兩種方法可以做到這一點。上面顯示的更新鏈有一個、default=true、屬性,將用于任何更新處理程序。

另一種更明確的方法是使用 InitParams 來設(shè)置所有/update請求處理程序的默認(rèn)值:

<initParams path="/update/**">
  <lst name="defaults">
    <str name="update.chain">add-unknown-fields-to-the-schema</str>
  </lst>
</initParams>
Tip:完成所有這些更改后,應(yīng)重新啟動 Solr 或重新加載內(nèi)核。

禁用自動字段猜測

使用 update.autoCreateFields 屬性可以禁用自動字段創(chuàng)建。要做到這一點,您可以使用 Config API 和命令,例如:

curl http://host:8983/solr/mycollection/config -d '{"set-user-property": {"update.autoCreateFields":"false"}}'

索引文件的例子

一旦啟用了無架構(gòu)模式(無論是手動配置模式還是使用 _defaultconfigset),包含未在架構(gòu)中定義的字段的文檔將使用自動添加到架構(gòu)的猜測字段類型進(jìn)行索引。

例如,添加一個 CSV 文檔會導(dǎo)致未知的字段被添加,字段類型基于值:

curl "http://localhost:8983/solr/gettingstarted/update?commit=true" -H "Content-type:application/csv" -d '
id,Artist,Album,Released,Rating,FromDistributor,Sold
44C,Old Shews,Mead for Walking,1988-08-13,0.01,14,0'

輸出指示成功:

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

架構(gòu)中的字段(輸出自:curl http://localhost:8983/solr/gettingstarted/schema/fields):

{
  "responseHeader":{
    "status":0,
    "QTime":2},
  "fields":[{
      "name":"Album",
      "type":"text_general"},
    {
      "name":"Artist",
      "type":"text_general"},
    {
      "name":"FromDistributor",
      "type":"plongs"},
    {
      "name":"Rating",
      "type":"pdoubles"},
    {
      "name":"Released",
      "type":"pdates"},
    {
      "name":"Sold",
      "type":"plongs"},
    {
      "name":"_root_", ...},
    {
      "name":"_text_", ...},
    {
      "name":"_version_", ...},
    {
      "name":"id", ...}
]}

另外字符串版本的文本字段被索引,使用 copyFields 到 *_str 動態(tài)字段:(輸出:curl http://localhost:8983/solr/gettingstarted/schema/copyfields):

{
  "responseHeader":{
    "status":0,
    "QTime":0},
  "copyFields":[{
      "source":"Artist",
      "dest":"Artist_str",
      "maxChars":256},
    {
      "source":"Album",
      "dest":"Album_str",
      "maxChars":256}]}

您仍然可以顯式:即使您希望對大多數(shù)字段使用無架構(gòu)模式,您仍然可以使用架構(gòu) API 在索引使用它們的文檔之前先用創(chuàng)建的類型先行創(chuàng)建一些字段。

在內(nèi)部,架構(gòu) API 和架構(gòu)更新處理器都使用相同的托管架構(gòu)功能。

此外,如果不需要文本字段的 * _str 版本,則可以從自動生成的架構(gòu)中刪除 copyField 定義,并且由于現(xiàn)在定義了原始字段,因此不會重新添加。

一旦一個字段被添加到架構(gòu),其字段類型是固定的。因此,添加具有與先前猜測的字段類型沖突的字段值的文檔將失敗。例如,在添加上面的文檔之后,“ Sold” 字段具有 fieldType plongs,但是下面的文檔在該字段中具有非整數(shù)十進(jìn)制值:
curl "http://localhost:8983/solr/gettingstarted/update?commit=true" -H "Content-type:application/csv" -d '
id,Description,Sold
19F,Cassettes by the pound,4.93'

此文檔將失敗,如以下輸出所示:

<response>
  <lst name="responseHeader">
    <int name="status">400</int>
    <int name="QTime">7</int>
  </lst>
  <lst name="error">
    <str name="msg">ERROR: [doc=19F] Error adding field 'Sold'='4.93' msg=For input string: "4.93"</str>
    <int name="code">400</int>
  </lst>
</response>
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號