solr如何建立索引的_solr查询

solr如何建立索引的_solr查询Solr7.5利用DIH导入结构化数据构建索引_solrdihdatasource

才疏学浅,欢迎批评指正

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.导入数据
在这里插入图片描述
各参数的含义如下

参数名称 取值 意义
command full-import/delta-import/status/reload-config/abort 全量导入/增量导入/导入的状态/重新载入配置文件/终止导入
verbose true/false 是否输出详细的步骤
clean true/false 是否删除原有的全部索引
commit true/false 导入后是否提交
optimize true/false 是否优化索引,优化索引会提高检索效率,但会增加导入的时间
debug true/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不同

今天的文章solr如何建立索引的_solr查询分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83326.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注