关于数据导入更为详细的介绍,见官方文档DataImport部分
一、创建db-data-config.xml文件
进入customData的文件夹,在customData这个core的文件夹下加新建db-data-config.xml文件
mkdir -p db/conf
touch db-data-config.xml
文件内容如下:
1、配置数据源,使用的是MySQL,数据源的type是JdbcDataSource.此外solr还提供了ContentStreamDataSource、FieldReaderDataSource、FileDataSource、URLDataSource具体文档可参考DataImport下的DataSources部分.
2、document下配置要导入到solr的实体,document可以有多个entity
3、entity属性介绍:
name-实体名字
pk-数据表的主键
query-全量导入时候的查询
deltaQuery-增量导入时查询出来的id语句,这里的判定标准是update字段时间大于最后的导入时间
deletedQuery-获取删除的id
deltaImportQuery-增量导入时候的查询,这里的id来自于上面的两个查询出来的id,在最后一次导入solr至本次导入期间变动的数据的id。
说明:如果增量更新时不想根据id进行更新,而是其他字段呢,那么上面的deletedQuery和deltaQuery查询可以将select中的id换成想要的字段,同时在deltaImportQuery查询里将条件换成 ${dataimporter.delta.想要的列名} 即可
field column-数据表中的字段名字,name-solr中的Field,就是第一篇文章中在managed-schema中配置的Field
<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
<dataSource
type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/dhb"
user="root"
password="12345"
batchSize="-1"/>
<document>
<entity name="user" pk="id"
query="SELECT id,name,age FROM user WHERE del = 0"
deltaQuery="SELECT id FROM user WHERE updated > '${dataimporter.last_index_time}' "
deletedPkQuery="SELECT id FROM user WHERE del = 1"
deltaImportQuery="SELECT id,name,age FROM user WHERE id = ${dataimporter.delta.id} ">
<field column="id" name="userId"/>
<field column="name" name="name"/>
<field column="age" name="age"/>
</entity>
</document>
</dataConfig>
这里jdbc设置数据库连接地址,用户名,密码,在最后还设置了batchSize="-1"。意思是每次查询拿到的结果集一行一行拉取。详细说明见文档说明
二、在customData文件夹下的conf文件夹下的solrconfig.xml配置DataImportHandler
1、添加DataImportHandler
<str>标签内是第一步中db-data-config.xml文件的位置
<!-- 数据库导入配置的dataimportHandler -->
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">/usr/local/var/lib/solr/customData/db/conf/db-data-config.xml</str>
</lst>
</requestHandler>
2、配置jar包路径
因为是MySQL数据库,要导入数据,需要一个MySQL的驱动jar包,还有DataImportHandler的包,同样在solrconfig.xml文件中添加
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-.*\.jar"/>
<lib dir="${solr.install.dir:../../../..}/dist/" regex="mysql-connector-java-.*\.jar"/>
建议把MySQL的jar包放到solr安装目录下的dist文件夹目录下,因为如果存在多个core,不需要每个core单独建立文件夹存放共有的jar包,dataimporthandlerjar同理。
说明:${solr.install.dir:}代表solr的安装目录,如果不清楚在哪,可以在solr控制台->Dashboard的左下角找到,其中还显示了日志的位置、GC日志的位置以及其他配置
三、全量导入/增量导入
1、重启solr之后,进入solr控制台->customData->Dataimport
2、command有full-import(全量导入)、delta-import(增量导入),第一次导入选择全量导入,根据情况选择是否勾选clean
3、在Entity中选择要导入的entity
4、点击Execute
5、Query一下,查看是否导入成功
说明:如果没查到数据,建议去Logging面板位置查看是否有报错日志,如果有,进入solr的日志文件夹下面查看solr.log内容定位错误
6、修改或者删除数据,点击delta-import,选择增量导入->Execute,再去Query一下,查看是否导入成功
四、定时增量导入数据
实际生产过程中,可能需要周期性的增量导入数据,
1、不可能手动去solr的控制台点一下,浪费时间、浪费精力
2、可以在实际业务代码中建立定时任务,视情况而定
在翻阅了solr的官方文档之后,没有找到提供定时任务的配置,倒是网上有关于solr的官方的定时任务的jar包,solr官方scheduler下载地址,不过因为官方的jar有bug,网上也有很多针对此jar的修复版本,如有需要,自行查找。
官方为什么没有再提供关于定时任务的jar包的维护呢,官方文档说明:
可以看到,solr官方表示,因为现代很多操作系统都已经支持定时任务的创建,所有solr不会再重复造轮子,所谓的定时任务jar不过是官方初期的一个简单的支持即可,更多关于官方的wiki参见OldWiki部分
3、既然操作系统本身提供定时任务,那么直接在操作系统中创建定时任务即可,使用crontab命令创建定时任务
crontab -u 用户 -e
此命令执行完毕会打开vi编辑器,在编辑器中输入要执行的命令即可,每一分钟增量导入customData这个core一次
*/1 * * * * curl http://localhost:8983/solr/customData/dataimport?command=delta-import&clean=false&commit=true
说明:
关于crontab命令使用帮助可参考菜鸟教程中关于crontab部分
如果想要删除定时任务可以
crontab -u 用户 -r
4、修改数据,等待一分钟,Query一下,查看solr中的数据是否更新了
五、导入过程中针对数据库tingint字段的问题
当数据库中字段类型为tinyint时,并且长度为1时,当我们在DataImport的时候,会自动转为boolean类型的字符串true,false.但是solr中的field我们定义的pint,这个时候就会报错。如下图
可以看到,这时的tinyint变为了字符串false。怎么能够使tinyint不被转为true或者false的字符串呢。修改一下查询语句,将data-config.xml中的查询语句,针对具体的tinyint字段做一下改变。如下图
其实就是做了一个隐式转换。
也可以不修改查询,修改field为boolean类型.
六、关于multiValued类型如何导入?
multiValued类型的field代表该field具有多个值,那么导入过程中,dataImportHandler如何识别呢。为entity配置正确的transformer,并在对应的字段上配置规则
使用如下配置
使用正则的Transformer,当查出结果集中subject_id字段的值是以,分隔的,则将多个值转为multiValued的每一部分。即可完成multiValued类型的field的导入
更多关于Transformer的介绍,请看官方文档
七、关于DataImportHandler(简称DIH)的最后介绍
1、根据官方文档显示,在solr9中,将会被移除,数据导入的功能将会采用第三方插件的形式提供支持
2、DIH包括四大部分,DataSource-读取原始数据用的、Entity-对应原始数据和solr中的document、Processor-将entity转换并添加到solr中的工具、Transformer-对某些字段进行转换处理。每一部分都有不同类型,实际运用过程中根据具体场景参考官方文档进行配置即可。