大概在 solr 1.3 刚出来的时候(2008 年底)就用过 DataImportHandler(DIH),当时觉得很方便的。后来由于有好多限制,就自己写了个做索引的框架。现有个简单的应用要用 dih 来做(小数据量的表,可以用它来做)。备忘记录下。
DataImportHandler 最大的优点是基本不用写代码,把数据库(其实也可以用 http/file 资源)中的记录放到索引中。现大概看下步骤:
1、编辑 solrconfig.xml 注册一个请求 uri 为 "/dataimport" 的请求处理器(org.apache.solr.handler.dataimport.DataImportHandler),代码如:
- <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
- <lst name="defaults">
- <str name="config">data-config.xml</str>
- </lst>
- </requestHandler>
2、创建 data-config.xml 文件放到 solr.home/conf 目录下,内容如下:
- <dataConfig>
- <dataSource type="JdbcDataSource"
- driver="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost/dbname"
- user="user-name"
- password="password"/>
- <document>
- <entity name="id"
- query="select id,name from mytable">
- </entity>
- </document>
- </dataConfig>
3、在 schema.xml 里创建 id 与 name 的字段声明。
4、把 mysql 的 jdbc.jar 放到 solr.home/lib 目录下。
5、启动 solr 后,执行命令:
http://localhost:8080/solr/dataimport?command=full-import 这 url 告诉 solr 做全量索引,做索引中会删除所有数据。当然也可以用 clean=false 参数来告诉它不删除,但也会删除相同id的(在 scheam.xml 的uniqueKey 声明的)。http://localhost:8080/solr/dataimport?command=full-import&clean=false
上面的是 mysql 字段与 scheam.xml 声明的一样,当然不一样时可以用 sql 的 as 来使它们一样。
还可以用 data-config.xml 里指定,如:
- <dataConfig>
- <dataSource type="JdbcDataSource"
- driver="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost/dbname"
- user="user-name"
- password="password"/>
- <document>
- <entity name="id"
- query="select id,name from mytable">
- <field column="id" name="solr_id"/>
- <field column="name" name="solr_name"/>
- </entity>
- </document>
- </dataConfig>
entity/field 中的 name 是指 scheam.xml 里指定的,column 是 sql 里出来的字段。
大多数,做索引时的数据不是在一个表里的,比较一对多的。DIH 还提供多表取数据。
把 data-config.xml 改为:
- <dataConfig>
- <dataSource type="JdbcDataSource"
- driver="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost/dbname"
- user="user-name"
- password="password"/>
- <document>
- <entity name="outer"
- query="select id,name,desc from mytable">
- <field column="id" name="solr_id"/>
- <field column="name" name="solr_name"/>
- <entity name="inner"
- query="select details from another_table where id ='${outer.id}'">
- <field column="details" name="solr_details"/>
- </entity>
- </entity>
- </document>
- </dataConfig>
在 scheam.xml 里指定 solr_details 字段为多值的 multiValued="true"。在上面 inner entity 里的 sql 语句可以加参数 ${outer.id} 就是 mytable 的 id 字段。
修改好后,重启,再做一次索引就有效果了,一对多一个缺点是会有 N+1 个 sql 查询。对小数据量的索引合适用 solr data import。