solr_專題:通過 Data Import Handler 添加結構化數據

一、什麼是 Data Import Handler?

許多搜索應用存儲了以結構化數據存儲來創建索引的內容,例如關係數據庫。Data Import Handler 提供了一種機制以便從數據存儲中導入內容併爲之建立索引。除了關係數據庫,DIH 還能夠爲 HTTP 基礎數據源(如 RSS 和 新聞摘要),郵件存儲庫和結構化 XML(XPath 處理器來生成域)。

二、基礎概念和術語

1、Transformer(改造器):每一個有實體匹配的域集合可以選擇性的被改造。這個過程可能會修改域,創建一個新的域或者將一個單行生成多行(或文檔)。在 DIH 中有幾個內置的改造器,它們可以用來修改日期和去除 HTML。我們也可以通過公共的接口寫自定義的改造器。

2、Processor(處理器):實體處理器可以從數據源中提取內容,改造內容並添加到索引中。我們可以用自定義的實體處理器來擴展或代替系統提供的實體處理器。

3、Entity(實體):從概念上講,實體會生成一個文檔集合,包含了多個域。然後由 Solr 創建索引。對於關係數據庫的數據源,一個實體可以是一張視圖或表(可以由一個或多個 SQL 命令處理生成具有一個或多個列(域)的行(文檔)集合。

4、Datasource(數據源):定義了數據的位置。對於一個數據庫而言,它是數據庫連接 DSN。對於 HTTP 而言,它是一個基地址(base URL)

三、配置

1、配置 solrconfig.xml

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
  <lst name="defaults">
    <str name="config">/path/to/my/DIHconfigfile.xml</str>
  </lst>
</requestHandler>
唯一的必填參數是 config 參數,它指明瞭 DIH 配置文件的地址。該配置文件包含了數據源的說明:如何匹配數據,匹配哪些數據和如何處理數據以生成索引文檔。

我們可以有多個 DIH 配置文件。每一個文件要求在 solrconfig.xml 中有一個獨立的定義來指明文件路徑。

2、配置 DIH 配置文件

下面的例子中提取了一個數據庫中的四張表數據。

<dataConfig>
	<!-- 
		 The first element is the dataSource, in this case an HSQLDB database.
		 The path to the JDBC driver and the JDBC URL and login credentials are all specified here.
		 Other permissible attributes include whether or not to autocommit to Solr, the batchsize
		 used in the JDBC connection, a 'readOnly' flag. 
		 The password attribute is optional if there is no password set for the DB.
		 這第一個元素是 dataSource(數據源),這個例子中是 HSQLDB 數據庫。
		 這裏包括了數據庫驅動,數據庫連接地址和登錄信息。
		 其他的屬性包括是否自動提交到 Solr 服務器,數據庫連接的批量處理大小,是否只讀。
		 如果數據庫沒有密碼,那麼 password 屬性是可以不填的。
		 
	-->
	<dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:./example-DIH/hsqldb/ex" user="sa" password="secret"/>
	<!--
	Alternately the password can be encrypted as follows. This is the value obtained as a result of the command
	openssl enc -aes-128-cbc -a -salt -in pwd.txt
	password="U2FsdGVkX18QMjY0yfCqlfBMvAB4d3XkwY96L7gfO2o=" 
	WHen the password is encrypted, you must provide an extra attribute
	encryptKeyFile="/location/of/encryptionkey"
	This file should a text file with a single line containing the encrypt/decrypt password
	password 是可以通過下面方法來進行加密的。
	password="U2FsdGVkX18QMjY0yfCqlfBMvAB4d3XkwY96L7gfO2o=" 
	是通過控制 enc -aes-128-cbc -a -salt -in pwd.txt 來求得的。
	當密碼被加密後,我們必須提供額外的屬性 encryptKeyFile="/location/of/encryptionkey"
	這個文件是一個 text 文件,只有一行,包含了 加密/解密 的密碼
	 
	-->
	<!-- A 'document' element follows, containing multiple 'entity' elements.
		 Note that 'entity' elements can be nested, and this allows the entity
		 relationships in the sample database to be mirrored here, so that we can
		 generate a denormalized Solr record which may include multiple features
		 for one item, for instance 
		 下面的 document 元素,包含了多個 entity 元素。注意 entity 元素是可以嵌套的
		 ,這表示了實體在相同數據庫中的關係映射,以至於我們能夠生成一個非規範化的 Solr
		 記錄,這條記錄可能包含了多個特性(對於一項或一個實例)
		 -->
  <document>
 
	<!-- The possible attributes for the entity element are described below.
		 Entity elements may contain one or more 'field' elements, which map
		 the data source field names to Solr fields, and optionally specify
		 per-field transformations 
		 下面描述了 entity 元素的一些屬性。entity 元素包含了一個或多個 field 元素,
		 這些元素將數據源的字段名稱與 Solr 域進行映射,可以選擇性的指明每個域的改造內容。
		 -->
	<!-- this entity is the 'root' entity.(這個 entity 是 root(根) 實體 -->
    <entity name="item" query="select * from item"
            deltaQuery="select id from item where last_modified > '${dataimporter.last_index_time}'">
      <field column="NAME" name="name" />
 
	<!-- This entity is nested and reflects the one-to-many relationship between an item and its multiple features.
		 Note the use of variables; ${item.ID} is the value of the column 'ID' for the current item
		 ('item' referring to the entity name)  
		 這個 entity 是嵌套的,在項和它的多特徵之間反應了一對多的關係。注意:變量的使用 ${item.ID} 
		 是當前項對應的 ID 字段屬性值
		 -->
      <entity name="feature" 
              query="select DESCRIPTION from FEATURE where ITEM_ID='${item.ID}'"
              deltaQuery="select ITEM_ID from FEATURE where last_modified > '${dataimporter.last_index_time}'"
              parentDeltaQuery="select ID from item where ID=${feature.ITEM_ID}">
        <field name="features" column="DESCRIPTION" />
      </entity>
      <entity name="item_category"
              query="select CATEGORY_ID from item_category where ITEM_ID='${item.ID}'"
              deltaQuery="select ITEM_ID, CATEGORY_ID from item_category where last_modified > '${dataimporter.last_index_time}'"
              parentDeltaQuery="select ID from item where ID=${item_category.ITEM_ID}">
        <entity name="category"
                query="select DESCRIPTION from category where ID = '${item_category.CATEGORY_ID}'"
                deltaQuery="select ID from category where last_modified > '${dataimporter.last_index_time}'"
                parentDeltaQuery="select ITEM_ID, CATEGORY_ID from item_category where CATEGORY_ID=${category.ID}">
          <field column="description" name="cat" />
        </entity>
      </entity>
    </entity>
  </document>
</dataConfig>
Datasource 也可以在 solrconfig.xml 文件中指定。但是一定要在 solrconfig.xml 文件處理器中的默認部分指定。然而,這些不會被解析知道主要的配置加載完成後。全部的配置也可以通過使用

dataConfig 參數解析爲一個請求參數。當配置出現錯誤時,錯誤信息將以 XML 格式返回。

reload-config 命令對於驗證一個新的配置文件時有用的,或者如果你想要指定一個文件,加載它,並且不想在導入時重新加載它。如果有一個 XML  錯誤在配置中,那麼錯誤信息會以 xml 格式返回。我們可以解決這個問題然後執行 reload-config 命令。

3、請求參數

配置中的請求參數可以被佔位符  ${dataimporter.request.paramname} 代替

<dataSource driver="org.hsqldb.jdbcDriver" url="${dataimporter.request.jdbcurl}" user="${dataimporter.request.jdbcuser}" password=${dataimporter.request.jdbcpassword} />
然後,這些參數可以通過 full-import 命令設置或者定義在 solrconfig.xml 文件的 <defaults> 中。格式如下:

dataimport?command=full-import&jdbcurl=jdbc:hsqldb:./example-DIH/hsqldb/ex&jdbcuser=sa&jdbcpassword=secret

三、Data Import Handler 命令

DIH 命令通過 HTTP 請求發送到 Solr。

1、abort:終止正在執行的操作。格式:http://<host>:<port>/ solr/ <collection_name>/ dataimport? command=abort

2、delta-import:用於增量導入和變化檢查。格式: http://<host>:<port>/ solr/ <collection_name>/ dataimport? command=delta-import。當 SqlEntityProcessor  支持增量導入時,它也可以像 full-import 一樣支持清除,提交,優化和測試。

3、full-import:該命令將立即返回。這個操作將在一個新的線程中開始而且在響應中的 status 屬性應該顯示爲 busy。這個操作執行的時間依賴於數據集的大小。在 full-import 期間查詢不會被阻塞。當 full-import 命令執行時,該操作的開始時間將被存儲在 conf/dataimport.properties 文件中。被存儲的時間戳當 delta-import 命令執行時會用到。格式:http://<host>:<port>/ solr/ <collection_name>/ dataimport? command=full-import

4、reload-config:如果配置文件已經改變,我們又不想重啓服務器,那麼可以執行該命令。格式:http://<host>:<port>/solr/<collection_name>/command=reload-config

5、status:該命令返回被創建和刪除的文檔數量,查詢信息,行匹配等。格式: http://<host>:<port>/ solr/ <collection_name>/ dataimport? command=status

6、show-config:相應配置

一)、full-import 命令的參數:

1、clean:默認值爲 true。表明在創建索引前是否清除以創建的索引

2、commit:默認值爲 true。表明操作之後是否提交

3、debug:默認值爲 false。以測試模式運行命令。它適用於交互式開發模式。注意:在測試模式下,文檔是不會自動提交的。如果我們既想要運行測試模式又想自動提交,那麼需要添加 commit=true 到請求到參數中。

4、entity:配置文件<document> 標籤下的 entity 名稱。通過該屬性選擇性的執行一個或多個 entity。多實體參數能夠用來一次運行多個實體,如果沒有合適的,那麼全部的實體都將被執行。

5、optimize:默認值爲 true。表明在操作後是否進行優化

6、synchronous:默認值爲 false。表明如果導入沒有完成那麼將阻塞請求

四、屬性寫入

properWriter 元素爲 delta 查詢定義了數據格式和區域。它是一個可選的配置。直接添加到 DIH 配置文件的 dataConfig 元素中就行。

<propertyWriter dateFormat="yyyy-MM-dd HH:mm:ss" type="SimplePropertiesWriter" directory="data" filename="my_dih.properties" locale="en_US" />
1、dateFormat:如果需要將日期轉換爲文本,將使用java.text.SimpleDateFormat。默認格式爲:yyyy-MM-dd HH:mm:ss

2、type:實現類。如果沒有云設置將使用 SimplePropertiesWriter。如果使用雲,將使用  ZKPropertiesWriter。如果沒有指定,那麼默認選擇恰當的類,當然這依賴於雲模型是否啓用。

3、locale:區域,默認爲 ROOT 區域。它必須指明那個國家的語言。

4、directory:默認值 conf。屬性文件的目錄

5、filename:屬性文件的名稱。如果沒有定義,默認與 requestHandler 名稱相同(在 solrconfig.xml 文件中定義)

五、數據源

數據源指明瞭數據的來源和類型。某些情況下,一些數據源由相關的實體處理器來配置。數據源也可以配置在 solrconfig.xml 中,當我們有多個不同的運行環境時(開發、測試和生產)這是非常有用的。我們也可以通過編寫繼承 org.apache.solr.handler.dataimport.DataSource 的類來定製數據源。數據源的名稱和類型是必須要設置的。數據源一共有:

1、contentStreamDataSource:

這個將 Post 數據作爲數據源。實體處理器使用了 <Reader> 標籤時會使用這個數據源。

2、FieldReaderDataSource:

當數據庫文件包含 XML 而且你希望使用 XPathEntityProcessor 時,使用該數據源。我們應該設置一個配置,JDBC 和 FieldReader 數據源,還有兩個實體,格式如下:

<dataSource name="a1" driver="org.hsqldb.jdbcDriver" ...  />
<dataSource name="a2" type=FieldReaderDataSource" />
<document>
 
  <!-- processor for database -->
   
  <entity name ="e1" dataSource="a1" processor="SqlEntityProcessor" pk="docid"
          query="select * from t1 ...">
 
    <!-- nested XpathEntity; the field in the parent which is to be used for
         Xpath is set in the "datafield" attribute in place of the "url" attribute -->
    
    <entity name="e2" dataSource="a2" processor="XPathEntityProcessor"
            dataField="e1.fieldToUseForXPath">
 
      <!-- Xpath configuration follows -->
      ...
    </entity>
  </entity>

3、FileDataSource:

從硬盤上的文件中匹配文檔。








































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章