DIH中添加不同的数据源
需求:从mysql数据库中读取一个知识记录,从记录表中的字段值中获取一个文件路径,读取xml文件,xml文件中可能包含多个文档内容。建立索引。
xml文件样例:
<?xml version="1.0" encoding="utf-8"?> <docs> <data> <id>1</id> <title>测试数据</title> <content>测试内容</content> <crtime>2014-10-13 16:10:33</crtime> <templateid>201</templateid> <price>12.11</price> </data> <data> <id>2</id> <title>测试数据1</title> <content>测试内容1</content> <crtime>2014-10-12 16:10:33</crtime> <templateid>202</templateid> <price>20.11</price> </data> </docs>
mysql数据格式样例:
CREATE TABLE `gx_kmsindex` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `docid` BIGINT(20) COMMENT '知识ID', `path` VARCHAR(200) DEFAULT NULL COMMENT '知识xml文件路径', `templateid` VARCHAR(20) NOT NULL COMMENT '知识模板id', `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', `type` VARCHAR(20) NOT NULL COMMENT '知识操作类型,add/update/delete', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
当为新增、更新知识时,docid可以为空,当为删除知识时,docid为必填项。
处理方案:
1、schema.xml中配置field:
<field name="id" type="string" indexed="true" stored="true" required="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
<field name="title" type="text_ik" indexed="true" stored="true" termVectors="true"/>
<field name="content" type="text_ik" indexed="true" stored="true" termVectors="true"/>
<field name="crtime" type="date" indexed="true" stored="true" />
<field name="templateid" type="string" indexed="true" stored="true" />
<field name="price" type="double" indexed="true" stored="true" />
2、solrconfig.xml中配置handler:
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">mysql-data-config.xml</str>
</lst>
</requestHandler>
3、配置mysql-data-config.xml
<dataConfig>
<dataSource name="jdbc" type="JdbcDataSource" driver="com.mysql.jdbc.Driver"
batchSize="-1" url="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8"
user="root" password="root" />
<dataSource name="file" type="FileDataSource" encoding="utf-8" />
<document>
<entity name="kms" dataSource="jdbc"
query="SELECT path FROM gx_kmsindex ORDER BY TIME ASC" transformer="DateFormatTransformer">
<entity dataSource="file" name="xml" url="${kms.path}"
processor="XPathEntityProcessor" forEach="/docs/data/" transformer="DateFormatTransformer">
<field column="id" xpath="/docs/data/id" />
<field column="title" xpath="/docs/data/title" />
<field column="content" xpath="/docs/data/content" />
<field column="crtime" xpath="/docs/data/crtime"
dateTimeFormat="yyyy-MM-dd HH:mm:ss" />
<field column="templateid" xpath="/docs/data/templateid" />
<field column="price" xpath="/docs/data/price" />
</entity>
</entity>
</document>
</dataConfig>
4、在后台建立索引,发现只抽取了一条数据记录。
按照道理,应该两条数据都能抽取。经过排查,是rootEntity属性的问题。在kms实体中,没有设置rootEntity属性,默认为true的。这样就把gx_kmsindex当作了根实体,
rootEntity="true" 表示它的文档会被Solr索引。如果rootEntity属性被显式地设置为false,那么DIH会反向查找,直到找到一个实体配置没有设置为false的。可以有子实体(sub-entities),它通常为每个父文档执行一次,并通常由父文档引用来缩小查找范围。子实体的文档会合并到根实体的文档中,如果多个子实体对相同的域产生了多个文档,那么根实体会产生一个多值域。
这里kms实体的rootEntity属性应该设置为“false”。xml实体才是用于索引的数据实体。所以xml实体rootEntity属性为true。这里采用默认属性值即可。修改后的mysql-data-config.xml:
<dataConfig>
<dataSource name="jdbc" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" batchSize="-1"
url="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8" user="root" password="root"/>
<dataSource name="file" type="FileDataSource" encoding="utf-8" />
<document>
<entity name="kms" dataSource="jdbc" query="SELECT path FROM gx_kmsindex ORDER BY TIME ASC"
transformer="DateFormatTransformer" rootEntity="false">
<entity dataSource="file" name="xml" url="${kms.path}" processor="XPathEntityProcessor"
forEach="/docs/data/" transformer="DateFormatTransformer" >
<field column="id" xpath="/docs/data/id" />
<field column="title" xpath="/docs/data/title" />
<field column="content" xpath="/docs/data/content" />
<field column="crtime" xpath="/docs/data/crtime" dateTimeFormat="yyyy-MM-dd HH:mm:ss"/>
<field column="templateid" xpath="/docs/data/templateid" />
<field column="price" xpath="/docs/data/price" />
</entity>
</entity>
</document>
</dataConfig>
5、修改后,重新建立索引: