Solr初探(五)---Solr7.5利用DIH导入结构化数据构建索引

才疏学浅,欢迎批评指正

Solr7.5利用DIH导入结构化数据构建索引

7.5利用DIH导入结构化数据构建索引

1.什么是DIH

按照solr7.5官方文档给出的说法:
The Data Import Handler (DIH) provides a mechanism for importing content from a data store and indexing it.

数据导入处理程序(DIH)提供了一种从数据存储中导入内容并对其进行索引的机制。

其中,
DataSource:指需要导入数据的数据源的位置
Entity
  对于solr而言:entity指一个包含多个字段的文档,solr对文档中的字段进行索引
  对于关系型数据库而言:entity指数据库中的一张表,数据库表中的一行(rows)对应solr中的一个文档(documents),表中的一个字段(columns ),对应solr中的一个字段(fields)

2.使用DIH

1.引入数据库驱动
在solr\server\solr-webapp\webapp\WEB-INF\lib下,放入需要的jar,这里是mysql
在这里插入图片描述
2.打开solrconfig.xml,添加如下内容:
在这里插入图片描述
1)引入DIH的jar包

  <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-\d.*\.jar" />

也就是dist文件夹中以solr-dataimporthandler开头的相关jar包
在这里插入图片描述
2)指定DIH配置文件

  <requestHandler name="/dataimport"
     class="org.apache.solr.handler.dataimport.DataImportHandler"> 
       <lst name="defaults"> 
          <str name="config">solr-data-config.xml</str> 
       </lst> 
  </requestHandler>

其中solr-data-config为DIH配置文件的文件名。

3.在conf文件夹下创建DIH的配置文件(这里为solr-data-config.xml)
在这里插入图片描述
4.配置DIH
在刚刚新建的solr-data-config.xml中添加如下内容

<dataConfig>
	<dataSource name="db_fileManagement" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" 
	url="jdbc:mysql://localhost:3306/db_fileManagement" user="root" password="123456"/>
    <document>
    <entity name="tb_test1" PK="DocumentNo" dataSource="db_fileManagement" 
    query="select * from tb_test1 where IS_DEL = '0'" 
    deltaQuery="select DocumentNo from tb_test1 where LAST_MODIFIED > '${dataimporter.tb_test1.last_index_time}'" 
    deltaImportQuery="select *  from tb_test1 where DocumentNo = '${dih.delta.DocumentNo}'" 
    deletedPkQuery="select DocumentNo from tb_test1 where IS_DEL = '1'">
      <field column="DocumentNo" name="document_number"/>
      <field column="PartNo" name="partno_s"/>
      <field column="No" name="no_s_c"/>
      <field column="PersonLiable" name="personliable_s_c"/>
      <field column="Title" name="title_ik_c"/>
      <field column="TABLE_ID" name="table_id_s"/>
    </entity>
    </document>
</dataConfig>

其中:
dataSource中为数据源的相关配置:

属性名作用
name数据库名称
type数据源类型
driver数据库驱动名称
url数据库地址
user用户密码
password用户密码

其中数据源类型还可以有FieldReaderDataSource等其他类型

entity配置相关SQL语句

属性名作用
name表的名称
PK表的主键名称
dataSource表所属的数据源的名称
query查询全量导入数据
deltaQuery查询增量导入数据的主键L,为deltaImportQuery作准备
deltaImportQuery根据从deltaQuery得到的主键,查询定义增量导入数据全部字段
deletedPkQuery查询需要删除数据的主键,删除这些记录

field配置数据库表中的记录与solr中document之间的关系

属性名作用
column字段在数据库表中的名称
name字段在solr中field的名称

4.导入数据
在这里插入图片描述
各参数的含义如下

参数名称取值意义
commandfull-import/delta-import/status/reload-config/abort全量导入/增量导入/导入的状态/重新载入配置文件/终止导入
verbosetrue/false是否输出详细的步骤
cleantrue/false是否删除原有的全部索引
committrue/false导入后是否提交
optimizetrue/false是否优化索引,优化索引会提高检索效率,但会增加导入的时间
debugtrue/false是否进入debug模式,该模式下数据不会提交
entity与solr-data-config中配置的entity名称一致所要导入的表的名称

使用solrj实现导入数据操作
全量导入

SolrQuery solrQuery = new SolrQuery();
solrQuery.setRequestHandler("/dataimport");//指定RequestHandler,默认为select
solrQuery.setParam("command","full-import");//指定导入方式
solrQuery.setParam("clean","false");//是否删除core中的索引,默认为true !!!
solrQuery.setParam("optimize","false");//操作结束后是否对索引进行优化
solrQuery.setParam("entity",tableName);//指定需要导入的table
solrQuery.setParam("commit","true");//是否提交
QueryResponse queryResponse = solrClient.query(solrQuery);
while(true){
    if(this.getImportInfo(solrClient)) {break;}
    Thread.sleep(1000);
}

增量导入

SolrQuery solrQuery = new SolrQuery();
solrQuery.setRequestHandler("/dataimport");//指定RequestHandler,默认为select
solrQuery.setParam("command","delta-import");//指定导入方式
solrQuery.setParam("clean","false");//是否删除core中的索引,默认为true !!!
solrQuery.setParam("optimize","false");//操作结束后是否对索引进行优化
solrQuery.setParam("entity",tableName);//指定需要导入的table
solrQuery.setParam("commit","true");//是否提交
QueryResponse queryResponse = solrClient.query(solrQuery);
while(true){
    if(this.getImportInfo(solrClient)) {break;}
    Thread.sleep(1000);
}

在全量或增量导入时,solr往往会需要一定时间,而此时虽然也返回queryResponse,但需要对其中的status进行判断,idle为导入成功的标志,busy则此时仍在导入

//getImportInfo方法
SolrQuery solrQuery = new SolrQuery();
solrQuery.setRequestHandler("/dataimport");//指定RequestHandler,默认为select
solrQuery.setParam("command","dataimport");
QueryResponse queryResponse = solrClient.query(solrQuery);
if(!"busy".equals(queryResponse.getResponse().asShallowMap().get("status")))
   return true;
else
   return false;

3.使用DIH中遇到的一些问题

1.时区问题
solr默认的是UTC时区,造成数据库中记录的时间与solr中索引构建的时间不一致,应修改UTC为东八区时间。
在bin下找到solr.cmd
在这里插入图片描述
修改

IF "%SOLR_TIMEZONE%"=="" set SOLR_TIMEZONE='UTC'

IF "%SOLR_TIMEZONE%"=="" set SOLR_TIMEZONE='UTC+8'

2.如何根据数据库中数据的变化自动增量构建索引

  1. 在数据库表中新增timestamp类型的字段,该字段会保存对应记录的更新的最新时间。这里的字段名称为LAST_MODIFIED。

  2. solr在导入数据时,在conf下的dataimport.properties文件下,会记录下每个entity的最新导入时间。

tb_test3.last_index_time=2019-05-13 16\:37\:33
tb_test2.last_index_time=2019-05-13 16\:42\:31
last_index_time=2019-05-15 21\:39\:03
tb_test1.last_index_time=2019-05-15 21\:39\:03
  1. 根据dataimport.properties文件中的last_index_time和数据库中记录变化的时间LAST_MODIFIED,选择需要增量导入的数据。因此定义deltaQuery为:
select DocumentNo from tb_test1 where LAST_MODIFIED > '${dataimporter.tb_test1.last_index_time}'

dataimporter.tb_test1.last_index_time,其中tb_test1为对应的表名

3.如何根据数据库中记录的删除,实现solr中索引的删除。

  1. 在数据库表中新增字段isDel,用以标识当前记录是否需要删除。当记录对应的索引需要删除时,将该字段置为1。(即实现数据的软删除)
  2. 调用接口,增量更新索引。获得需要被删除的记录的主键,删除索引
select DocumentNo from tb_test1 where IS_DEL = '1'
  1. 删除索引后,再删除数据库中字段为1的记录,即硬删除。从而实现数据库数据与索引数据的一致。

4.虽然solr可以实现不同数据源中导入不同数据库表中的数据,但这些表的表名必须各不相同,即使是在不同数据源下,也不能有相同的表名

5.导入数据时,可能会遇到不同表中有相同名称主键的问题,会造成主键的冲突。可以增加UUID,自动生成UUID,将UUID对应的field作为document的主键

  1. 在managed-schema文件中增加如下配置
<fieldType name="uuid" class="solr.UUIDField" indexed="true" docValues="true"/>

修改原id的field为

<field name="id" type="uuid" indexed="true" stored="true" required="true" multiValued="false" /> 

修改原_root_的field为

 <field name="_root_" type="uuid" indexed="true" stored="false" docValues="false" />

同时id作为uniqueKey不变

<uniqueKey>id</uniqueKey>

这样solr可以以UUID作为主键

  1. 在solrconfig.xml中增加
    <!-- 生成UUID -->
  <updateRequestProcessorChain name="uuid">
     <processor class="solr.UUIDUpdateProcessorFactory">
          <str name="fieldName">id</str>
     </processor>
     <processor class="solr.LogUpdateProcessorFactory" />
     <processor class="solr.DistributedUpdateProcessorFactory" />
     <processor class="solr.RunUpdateProcessorFactory" />
  </updateRequestProcessorChain>

修改

  <initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell,/browse,update">
    <lst name="defaults">
      <str name="df">text</str>
      <str name="update.chain">uuid</str>
    </lst>
  </initParams>
  <requestHandler name="/update/extract"
                  class="solr.extraction.ExtractingRequestHandler" >
    <lst name="defaults">
      <str name="uprefix">ignored_</str>
      <str name="update.chain">uuid</str>
    </lst>
  </requestHandler>
    <requestHandler name="/dataimport"
     class="org.apache.solr.handler.dataimport.DataImportHandler"> 
       <lst name="defaults"> 
          <str name="config">solr-data-config.xml</str> 
          <str name="update.chain">uuid</str>
       </lst> 
	</requestHandler>

这样可以solr可以自动生成UUID

6.富文本(word/pdf/txt/html)
DIH除了可以导入结构化数据外,还可以利用tika导入富文本,可见
http://lucene.apache.org/solr/guide/7_5/uploading-data-with-solr-cell-using-apache-tika.html

http://lucene.apache.org/solr/guide/7_5/uploading-structured-data-store-data-with-the-data-import-handler.html
其中的The TikaEntityProcessor和The FileListEntityProcessor部分

7.DIH配置文件中的PK可以与solr中的uniqueKey不同

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值