solr 4.8 mysql_solr4.8 DataImportHandler 从关系型数据库导入数据

1.    概述

大多数的应用程序将数据存储在关系数据库(例如oracle、mysql、sql service等等)。对这样的数据进行搜索是很常见的应用。对于这样的应用如果技术选型是Solr,就需要把数据从关系型数据库导入到solr服务器,为了解决这个问题,Apache提供了DataImportHandler,所谓的DataImportHandler就是提供一种可配置的方式向solr导入数据,可以一次全部导入,也可以增量导入,还可以声明式提供可配置的任务调度,让数据定时的从关系型数据库更新数据到solr服务器。

2.    使用步骤

将solr发布包下面的dist/solr-dataimporthandler-extras-4.8.0.jar 和 solr-dataimporthandler-4.8.0.jar

导入到solr的lib目录下面

在需要进行数据导入的core里面引入DataImportHandler 代码如下

/home/item /data-config.xml

从它的名字上,我们或许也可以猜到,DataImportHandler正是requestHandler的实现。

新建data-config.xml

在相应的目录创建上面的data-config.xml文件,不过这个文件一般都是放在conf目录下面,那么这时的应该这么写:

data-config.xml

4.配置data-config.xml

最简单的实例如下:

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/dih"

user="ickes"

password="ickes"/>

最后记得把相应数据库的驱动包导入,导入后重启tomcat,进入你的solr管理页面,如下图:

b42bef0c59e0d5fd658c70bfe10732c4.png

当然你可以可以再url里面直接这样请求:

http://192.168.238.133:8080/solr/dih_test/dataimport?command=full-import

所带参数含义:

commad:该参数可以取值:full-import、delta-import、reload-config、abort

full-import:代表全量导入;

delta-import:增量导入

reload-config : 如果data-config.xml已经改变,你不希望重启solr,而要重新加载配置时,就用这个值;

abort : 如果参数是该值,那么会终止一个在运行的操作;

其他参数:

clean : (default 'true'). 决定在建立索引之前,删除以前的索引;

commit : (default 'true'). 决定这个操作之后是否要commit;

optimize : (default 'true'). 决定这个操作之后是否要优化;

让一个实例跑起来是不是如此的简单,下面会循序渐进的深入……!

3.DataImportHandler的参数说明

在使用步骤中第一步:引入DataImportHandler,第二步:建立data-config.xml文件,这两个步骤是固定的,必须配置,说白了DataImportHandler需要配置就只有data-config.xml文件。

a) 配置数据源

如果只有一个数据源,那么可以像上面第一个实例一样配置,那么所有的entity节点中配置的sql都会引用该数据源。

如果有多个数据源,可以如下这么配置,在dataSource标签上面定义一个name的属性,注意这个name的名字必须唯一,然后在entity标签上面通过dataSource属性引用配置的dataSource。

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://db1-host/dbname"

user="xxx" password="xxx"/>

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://db1-host/dbname"

user="xxx" password="xxx"/>

多数据源配置就是如此的简单,你没有看错…..!

b) 配置entity

Entity的配置相对来说没有上面的那么” 如此的简单”,当然也是相当容易的,毕竟是Apache的东西,对吧!

DataImportHander为了能够从数据获得想要的数据,设计支持标准的sql规范.以下是entiry的属性含义,来源于官网的翻译,英语不是很好,这是根据我理解翻译的。如果你英语厉害,可以自己去官网上浏览学习,地址如下:http://wiki.apache.org/solr/DataImportHandler

name(必需的):name是唯一的,用以标识entity

processor:只有当datasource不是RDBMS时才是必需的。默认值是SqlEntityProcessor

transformer:转换器将会被应用到这个entity上,下面章节会继续详细介绍。

pk:entity的主键,它是可选的,但使用“增量导入”的时候是必需。它跟schema.xml中定义的uniqueKey没有必然的联系,但它们可以相同。

rootEntity:默认情况下,document元素下就是根实体了,如果没有根实体的话,直接在实体下面的实体将会被看做根实体。对于根实体对应的数据库中返回的数据的每一行,solr都将生成一个document。

query:是获取全部数据的SQL;用于全量导入

deltaQuery:查询出所有经过修改的记录的ID,可能是修改操作,添加操作,删除操作产生的;(此查询只对增量导入起作用,而且只能返回ID值,这个Id对应的是Entity标签的pk属性)

deletedPkQuery:此操作值查询那些数据库里伪删除的数据的ID(即isdelete标识为1的数据)solr通过它来删除索引里面对应的数据(此查询只对增量导入起作用,而且只能返回ID值,这个Id对应的是Entity标签的pk属性)

deltaImportQuery:获取增量数据时使用的SQL

parentDeltaQuer:从deltaQuery中取得当前表中更新的行,并把这些行提交给父表。因为,当子表中的一行发生改变时,我们需要更新它的父表的solr文档。

从关系型数据库导入数据到solr服务器建立索引,内容就这么多;

4.综合实例

本实例涵盖了solr从关系型数据库导入的全部,理解本实例是进行企业级开发的关键。

数据库模型的实体关系图如下:

d86776de6b1648b78d63acaf37482b04.png

简单解释上面的模型图:

Feature(我叫他特征表)表与item(项目表)是一对多的关系,feature是一方,item是多方,feature表通过item_id引用主表item的id

Item表与category(类别表)表是多对多的关系,该关系通过第三张表item_category进行关联,简单理解就是拆分为两个一对多的关系。这种设计相信大家在开发都干过

如下图所示(原谅的截图,让你不能复制,这是因为如果是文字,文档太丑了)是定义的与之对应的core的schema.xml文件,与数据库这个模型进行映射。

c1dc81582fcab47e45ca636a50789856.png     细心的读者可能注意到了feature_description(代表feature表的description字段)和categroy_description(代表categroy表的description字段)这两个字段的multiValued属性的值为ture,这是因为这两个字段与item表是多方的关系。

data-config.xml配置如下图所示这是单独的增量配置:

7c6d221fb4d9543faca34d0eb360ed3e.png

对上图entity标签(映射配置)解释如下:

这里, 根实体是一个名叫“item”的表,它的主键是id。我使用语句select id,name,manu,weight,price,includes from item读取数据,他的每一条记录都是对应solr的一个document。

从上面的数据库实体关系图可以看出他与feature是一对多的关系如下,注意了,我是怎么处理这种一对多的关系的。

如下图所示:

d7b945e78b314ea317dc80030583e444.png

相同地,我们将item和category连表(它们是多对多的关系)。注意了,我是怎样处理这种对对多的关系的。

如下图所示:

13f3fe3ebf512378714d8b0b7a265b97.png

上面的${item.id}表达式的含义相信你现在已经猜出他的含义了,不错他的含义就是引用他父entity中query属性在执行完sql从结果集中取出来的值。

文档写到这里,我们继续深入,上面的例子只是全量导入,下面看我怎么引入增量导入,这次我在item表上面加了一个字段create_time(创建时间),同时data-config.xml的配置如下图所示

fd518e454b11ef51e46bd8ae6fa566c1.png

这时我最顶层的entity标签中加入一个detaQuery的属性,该属性的含义为查询出所有经过修改的记录的ID ,可能是修改操作,添加操作,删除操作产生的(此查询只对增量导入起作用,而且只能返回ID值,这个Id对应的是Entity标签的pk属性) ;然后将这些更新过的数据,从数据库拉到solr服务器的索引中,更新索引,让数据同步。

该属性的sql条件中有一个表达式{dataimporter.last_index_time},是DataImporthandler传过来的变量,它指出“完全导入”或者“部分导入”的最后运行时间。你可以在data-config.xml文件中的sql的任何地方使用这个变量。对于每次的增量导入、和全量导入这个导入时间都会保存在conf/dataimport.properties文件中,以便下次导入时引用。

注意限制条件:deltaQuery :必须返回自己的pk

5.实例进阶

现在有一个问题,对于detaQuery属性可以发现数据库的更新操作,但是有些应用场景要求数据的删除不能物理删除,要求他必须伪删除,也就是在表中定义一个字段isDelete,来判断这条记录是否有效。对于这个问题你可能想到的方法是在solr进行查询时,加一个条件isdelete=0查询出有效不就可以了吗,但是这样做有一个不好的地方,那就是让索引冗余了,这些无效的数据保存在数据库中就可以了,不要交给solr;我相信企业在技术选型上选择solr的原因只有一个,那就是利用solr的建立的倒排索引,来提高检索速度,这样的话索引当然是越小越好,因此这种带isdelte=1的条件查询明显不是好的一个选择。

为了解决这个问题,Apache的攻城狮们在entity标签中引入了另外一个属性,deletedPkQuery这个属性的含义为:查询那些数据库里伪删除的数据的ID(即isdelete标识为1的数据)solr通过它来删除索引里面对应的无效数据  (此查询只对增量导入起作用,而且只能返回ID值,这个Id对应的是Entity标签的pk属性)。

为了测试这个过程,我在item表中又加了一个字段isDelete(国际惯例0代表有效、1代表无效)来标识这条记录是不是有效的,相应的我的data-config.xml变成如图下所示:

e7bcc57bc3b58829269bc4a29645956a.png

这时伪删除的场景业务模型得到了解决。

我还是循序渐进,接下来解决的问题是:对于上面的配置,有这么一个问题,那就是增量导入时,上面配置只能捕捉到父entity(也就是item表)数据的变动,从而将数据更新到solr,如果现在的业务是这样的,那就是当关联表(feature表、category表)的数据变动时也能联动更新索引,这个怎么做呢?强大的Apache当然考虑到了,说多了都是扯淡,直接上实例代码,如下图所示:

9d9afdc0c20f74e41e0c8e1560407cdc.png

从上面代码中可以看到,我在子entity标签中加入了parentDeltaQuer,跟deltaQuery属性,其中parentDeltaQuer属性的含义如下:从deltaQuery中取得当前表中更新的行,并把这些行提交给父表。因为,当子表中的一行发生改变时,我们需要更新它的父表的solr索引。这样一来上面的问题便得到了解决。

限制条件

子Entity的parentDeltaQuery必须引用自己的pk

子Entity的parentDeltaQuery必须返回父Entity的pk

看清楚了,一个是引用,一个是返回

6.原理

Full Import工作原理:

先删除当前core里面的所有数据;

执行本Entity的Query,获取所有数据;

针对每个行数据Row,获取pk,组装子Entity的Query;

执行子Entity的Query,获取子Entity的数据;

Delta Import工作原理:

执行Entity的deltaQuery,获取变化数据的pk;

合并所有子Entity parentDeltaQuery得到的主表中变化的pk;

(变化pk:包括数据中新增、修改、删除的pk,这里的变化是指数据库的变化)

得到变化pk以后,先从solr中删除在数据库中修改和删除过的索引,然后添加新增、修改、删除的索引

如果配置了deltaImportQuery,执行deltaImportQuery,将他获得数据全部插入

从这里可以看出deltaImportQuery往往是多余的,因为deltaQuery会将更新的数据插入(就已经包括了新增的数据)

7.数据同步总结

从oracle同步数据时,日期转换处理:

8.任务调度

任务调度有两种,想知道怎么使用这两种,请听下篇分析;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值