实际工作中,我们的业务数据在数据仓库(如mysql)中。我们需要把数据库中的数据同步到solr中,才能更好地做全文检索。这就需要DIH(Data Import Handler)来发挥作用。
初体验
官方文档是最好的第一手资料,http://lucene.apache.org/solr/guide/6_6/uploading-structured-data-store-data-with-the-data-import-handler.html
下载solr6.6后,执行以下命令,就可以看到solr data import handler的solr示例。
bin/solr -e dih
DIH配置
配置solrconfig.xml
在solrconfig.xml中注册Data Import Handler
<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 configuration file 的位置,该文件定义了数据同步到solr的方式。可以查看官方示例 example/example-DIH/solr/db/conf/db-data-config.xml
配置db-data-config.xml
很重要的文件,定义了数据从存储仓库(如DB)同步到solr的方式,官方的一个示例文件如下:
<dataConfig>
<dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:./example-DIH/hsqldb/ex"
user="sa" password="secret"/>
<document>
<entity name="item" query="select * from item"
deltaQuery="select id from item where last_modified >
'${dataimporter.last_index_time}'">
<field column="NAME" name="name" />
<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>
与该配置文件相对应的数据表如下:
item:
ID,NAME,MANU,WEIGHT,PRICE,POPULARITY,INCLUDES,LAST_MODIFIED
feature:
ITEM_ID,DESCRIPTION,LAST_MODIFIED
category:
ID,DESCRIPTION,LAST_MODIFIED
item_category:
ITEM_ID,CATEGORY_ID,LAST_MODIFIED
关于配置文件中的几个查询sql对应的属性名的介绍可以参考:
https://blog.csdn.net/wulantian/article/details/43051623
值得一提的是,由于document中嵌套关系的存在,实际生成的doc文档结构与数据仓库(如mysql)中的形式不太一致,但是这有时又是非常有效的,特别是存在一对多关系的时候。比如,mysql中的商品表item主键是id,另有一个商品尺寸表size,还有一个关联这两者的中间表item_size。一个商品可以有多个尺寸,如何存储到solr中,而且只有一条记录呢?这就是示例文档中嵌套的作用。
DIH请求参数
配置文件中的部分参数可以用占位符替代,如
<dataSource driver="org.hsqldb.jdbcDriver"
url="${dataimporter.request.jdbcurl}"
user="${dataimporter.request.jdbcuser}"
password="${dataimporter.request.jdbcpassword}" />
这些参数可以放到 url请求参数中,或者配置到solrconfig.xml的defaults中。全量请求示例如下
DIH命令集
dih的命令都是通过发送http请求完成的,具体支持的命令可以查看官方文档
http://lucene.apache.org/solr/guide/6_6/uploading-structured-data-store-data-with-the-data-import-handler.html#dataimporthandler-commands
主要有
abort 放弃当前执行的命令
delta-import 增量更新
full-import 全量更新
clean 清除solr文档
commit 操作后提交请求,默认true
debug 开启degug模式,默认false。当开启debug时,且想请求生效,需强制commit=true
synchronous 阻塞当前请求知道上一个请求完成,默认false,即非同步。
配置数据源
DIH支持多种数据源,这里只说明下JDBC数据源。
JDBC数据源包含属性driver, url, user, password, encryptKeyFile, batchSize。对于mysql数据库,设置batchSize==-1,否则容易造成内存溢出。