一般存储数据都会用到数据库,之前十几年关系型数据库大行其道,现在非关系性数据库(NoSql)如日中天,随着数据越来越来越多,人们发现关系型数据库的性能已经不能满足需要,经历了一番挣扎,从主-从(读-写)分离,到分库分表,虽然维持了一段时间,但是数据量很快就上来了,于是NoSql越来越显示出其在大数据时代的价值。

咳咳,不过这篇文章讲的却是从最流行的关系型数据库中导入数据到Solr,没办法,笔者还没用过NoSql,所以还是老老实实讲Mysql,哈哈。

导入需要的jar包

做过数据库开发的童鞋都知道,要想用数据可就需要连接数据库的接口,java上叫JDBC(Java Data Base Connectivity),别的语言也有类似的接口。

那么,这次我们需要两个jar包,分别是solr-dataimporthandler-5.5.0.jarmysql-connector-java-5.1.38-bin.jar,前一个可以在solr的解压目录下的dist目录中获取,后一个我想大家都可以找到的。

将这两个jar包复制到$Solr.Install.Dir/server/solr-webapp/webapp/WEB-INF/lib这个目录下。

配置导入设置

1. 默认dataImport功能在Solr5中是禁用的,需要在$SolrHome/conf/solrconfig.xml中添加如下配置开启数据导入功能:

 <!-- Data import from mysql 要放在<config></config>中哦-->
  <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,所以在solrconfig.xml同级目录下新建这个文件,贴出我的配置,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<dataConfig>   
<dataSource name="fromMysql"
          type="JdbcDataSource"   
          driver="com.mysql.jdbc.Driver"   
          url="jdbc:mysql://localhost:3306/tripsearch"   
          user="root"   
          password="root"/>   
<document>   
    <entity name="sight" query="SELECT * FROM sight" transformer="RegexTransformer">
         <field column="sight_id" name="sight_id"/> 
         <field column="sight_name" name="sight_name"/> 
         <field column="sight_score_ctrip" name="sight_score_ctrip"/>
         <field column="sight_intro" name="sight_intro"/> 
         <field column="sight_address" name="sight_address"/> 
         <field column="sight_coordinate" name="sight_coordinate"/> 
         <field column="sight_type" name="sight_type" splitBy=","/>
         <field column="pageurl" name="pageurl"/>
    </entity>   
</document>   

</dataConfig>

其中fromMysql为数据源自定义名称,随便取,没什么约束,type这是固定值,表示JDBC数据源,后面的driver表示JDBC驱动类,这跟你使用的数据库有关,url即JDBC链接URL,后面的user,password分别表示链接数据库的账号密码,下面的entity映射有点类似hiberante的mapping映射,column即数据库表的列名称,name即schema.xml中定义的域名称。

还有些设置项、参数不知道什么意思,后面后会说的。现在只要清楚field这个标签是设置数据库表中的列(column)和Solr中的字段的映射关系的。

另外:Solr中field还没有配置的,请先阅读3.1 Solr5配置文件参数解析

进行数据导入

1. 重启Solr,进入管理页面,选中trip这个Core,进入Dataimport这个选项。如果一切正常会出现如下图所示的界面。 solr-admin-ui-dataimporthandler-home

右面的那些代码是你点击Configuration后出现的,是data-config.xml文件中的内容,也是应该首先检查的地方,如果没有这些配置信息,说明数据库导入的配置文件没生效,是solrconfig.xml文件中开启导入功能的地方出错。

2. 开始导入,要注意command参数,它有两个选项,如下图: full-import:全量导入,它会覆盖原有的索引 delta-import:即增量导入,它会在原有索引的基础上追加

下面的几个多选框含义解释如下: verbose:这个选项设为true的话,会打印导入的一些中间过程的详细信息,有利于调试以及了解内部操作细节 clean:表示是否在导入数据创建索引之前先清空掉原有的索引 commit:表示是否立即提交索引 optimize:表示是否优化索引 debug: 表示是否开启调试模式

3.然后选择需要导入的Entity,点击Execute按钮开始执行数据导入操作,如图:

正常的话就开始进行导入了,如下图

我们可以通过Refresh Status这个按钮刷新状态,如果出现错误或者Fetched一直是0,那就表明有问题了,你要查看日志进行检查。如果导入成功,就会看到下图所示的情况:

查看OverView菜单,会看到文档信息。

在查询中点击Execute Query按钮,就能看到我们导进去并建好索引的信息,更具体的查询用法后面会讲到,下面是默认的查询,显示文档的所有信息。

较为复杂的字段映射

数据库单表多个字段到solr多值字段

例如我数据库一个表中有关于地址的几个字段,分别是国家、省份、地区这样的字段(sight_place_1, sight_place_2, sight_place_3..)我需要把这几个字段放到solr中一个多值字段sight_place中。

题外话:对于关系型数据库不应该这样建表的,至少要满足第二范式,但这里用mysql只是为了存数据。

其实对于这个需求比较容易实现,修改data-config.xml文件中的entity就行了,配置如下

<field column="sight_place_1" name="sight_place"/>
<field column="sight_place_2" name="sight_place"/>
<field column="sight_place_3" name="sight_place"/>
<field column="sight_place_4" name="sight_place"/>
<field column="sight_place_5" name="sight_place"/>

数据库单表单字段到solr多值字段

前提:数据库中的单字段中的数据包含多值信息,并且用分隔符分开。例如数据库中sight_type字段的值是

sight_name sight_type
故宫 古迹,世界文化遗产,历史建筑,博物馆
<entity name="sight" query="SELECT * FROM sight" transformer="RegexTransformer">
    <field column="sight_type" name="sight_type" splitBy=","/>
</entity>

这样,导入到sight_type中的数据就是多值的

sight_type{
    "博物馆",
    "历史建筑",
    "世界文化遗产",
    "古迹"
}

特别注意: entity的属性transformer要为RegexTransformer,字段映射field属性splitBy设置为你的分隔符

数据库中多表联查到solr多值字段

1. 对于熟悉sql语句的人来讲,通过相对复杂的查询语句可以查到任何条件的结果,例如下面要说的 group_concat

select sight_place_1,GROUP_CONCAT(sight_place_2) as subplace FROM sight GROUP BY sight_place_1

这条查询的结果是

sight_place_1 subplace
中国 北京,台湾,江苏,香港,宁夏,陕西

这样就回到了上面的方法了。当然这并不是多表,只是个简单的实例,你可以用更复杂的sql语句实现多表联查。

2. 另外solr也提供了子查询功能,例如下面的实例,更复杂的可以查看官方Wiki

<entity name="comment" pk="id" query="SELECT * FROM comment">
        <field column="blogpost_id" name="blogpost_id"/>
        <field column="comment_text" name="comment_text" />
        <entity name="comment_tags" pk="comment_id" query="SELECT * FROM comment_tags WHERE comment_id='${comment.id}'">
            <field column="tag" name="tag" />
        </entity>
</entity>

一些问题

不可行:多值字段按照下标取值 本来我想着取多值字段的sight_place的第二个值,就是省份,但最后发现这并不可行,solr中的多值应该就是个无序列表,但却可以发现在查询结果中,先插入的在下面,后插入的在上面,也不是真的无序。但没找到有序访问的方法。下面是关于这个问题的链接

Query specificly indexed value in multivalued field

Query a specific index value in a multivalue field in Solr

答案中建议我们可以用动态域(dynamic field)或者前缀的方式解决。

参考链接

  1. Uploading Structured Data Store Data with the Data Import Handler - solr5 Wiki

  2. Data Import Request Handler - solr4 Wiki

  3. Importing multi-valued field into Solr from mySQL using Solr Data Import Handler

  4. solr5.3.1从mysql导入索引

  5. 跟益达学Solr5之从MySQL数据库导入数据并索引

results matching ""

    No results matching ""