使用Solr索引MySQL数据

环境搭建

1、到apache下载solr,地址:http://mirrors.hust.edu.cn/apache/lucene/solr/

2、解压到某个目录

3、cd into D:\Solr\solr-4.10.3\example

4、Execute the server by “java -jar startup.jar”Solr会自动运行在自带的Jetty上

5、访问http://localhost:8983/solr/#/

创建MySQL数据

DataBase Name: mybatis

Table Name: user

Db.sql

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userName` varchar(50) DEFAULT NULL,
  `userAge` int(11) DEFAULT NULL,
  `userAddress` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (‘1‘, ‘summer‘, ‘30‘, ‘shanghai‘);
INSERT INTO `user` VALUES (‘2‘, ‘test1‘, ‘22‘, ‘suzhou‘);
INSERT INTO `user` VALUES (‘3‘, ‘test1‘, ‘29‘, ‘some place‘);
INSERT INTO `user` VALUES (‘4‘, ‘lu‘, ‘28‘, ‘some place‘);
INSERT INTO `user` VALUES (‘5‘, ‘xiaoxun‘, ‘27‘, ‘nanjing‘);

使用DataImportHandler导入并索引数据

1) 配置D:\Solr\solr-4.10.3\example\solr\collection1\conf\solrconfig.xml

在<requestHandler name="/select" class="solr.SearchHandler">前面上加上一个dataimport的处理的Handler

<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

<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
    <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/mybatis" user="root" password="luxx" batchSize="-1" />
  <document name="testDoc">
        <entity name="user" pk="id"
                query="select * from user">
            <field column="id" name="id"/>
           <field column="userName" name="userName"/>
            <field column="userAge" name="userAge"/>
            <field column="userAddress" name="userAddress"/>
     </entity>
  </document>
</dataConfig>

说明:

dataSource是数据库数据源。

Entity就是一张表对应的实体,pk是主键,query是查询语句。

Field对应一个字段,column是数据库里的column名,后面的name属性对应着Solr的Filed的名字。

3) 修改同目录下的schema.xml,这是Solr对数据库里的数据进行索引的模式

(1)保留_version_ 这个field

(2)添加索引字段:这里每个field的name要和data-config.xml里的entity的field的name一样,一一对应。

<field name="id" type="int" indexed="true" stored="true" required="true" multiValued="false" />

<!--<field name="id" type="int" indexed="true" stored="true" required="true" multiValued="false"/> -->

<field name="userName" type="text_general" indexed="true" stored="true" />

<field name="userAge" type="int" indexed="true" stored="true" />

<field name="userAddress" type="text_general" indexed="true" stored="true" />

(3)删除多余的field,删除copyField里的设置,这些用不上。注意:text这个field不能删除,否则Solr启动失败。

<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>

(4)设置唯一主键:<uniqueKey>id</uniqueKey>,注意:Solr中索引的主键默认是只支持type="string"字符串类型的,而我的数据库中id是int型的,会有问题,解决方法:修改同目录下的elevate.xml,注释掉下面2行,这貌似是Solr的Bug,原因不明。

<doc id="MA147LL/A" />
<doc id="IW-02" exclude="true" />

4)拷贝mysql-connector-java-5.1.22-bin.jar和solr-dataimporthandler-4.10.3.jar到D:\Solr\solr-4.10.3\example\solr-webapp\webapp\WEB-INF\lib。一个是mysql的java驱动,另一个在D:\Solr\solr-4.10.3\dist目录里,是org.apache.solr.handler.dataimport.DataImportHandler所在的jar。

重启Solr。

如果配置正确就可以启动成功。

solrconfig.xml是solr的基础文件,里面配置了各种web请求处理器、请求响应处理器、日志、缓存等。

schema.xml配置映射了各种数据类型的索引方案。分词器的配置、索引文档中包含的字段也在此配置。

索引测试

进入Solr主页,在Core Selector中选择collection1:http://localhost:8983/solr/#/collection1

点击Dataimport,Command选择full-import(默认),点击“Execute”,Refresh Status就可以看到结果:

Indexing completed. Added/Updated: 7 documents.Deleted 0 documents.

Requests: 1, Fetched: 7, Skipped: 0, Processed: 7

Started: 8 minutes ago

Query测试:在q中输入userName:test1进行检索就可以看到结果。

这里使用full-import索引了配置数据库中的全部数据,使用Solr可以查询对应的数据。

使用Solrj索引并检索数据

上面是使用Solr Admin页面上的功能测试索引和检索,也可以使用代码来操作Solr,下面的代码测试了在Solr索引中添加了一个User类实体,并通过查找所有的index来返回结果。

package com.solr.test;

import java.io.IOException;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocumentList;

import com.mybatis.test.model.User;

public class SolrTest {

    private static SolrServer server;

    private static final String DEFAULT_URL = "http://localhost:8983/solr/collection1";

    public static void init() {
        server = new HttpSolrServer(DEFAULT_URL);
    }

    public static void indexUser(User user){
        try {
            //添加user bean到索引库
            try {
                UpdateResponse response = server.addBean(user);
                server.commit();
                System.out.println(response.getStatus());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        }
    }

    //测试添加一个新的bean实例到索引
    public static void testIndexUser(){
        User user = new User();
        user.setId(8);
        user.setUserAddress("place");
        user.setUserName("cdebcdccga");
        user.setUserAge(83);

        indexUser(user);
    }

    public static void testQueryAll() {
        SolrQuery params = new SolrQuery();

        // 查询关键词,*:*代表所有属性、所有值,即所有index
        params.set("q", "*:*");

        // 分页,start=0就是从0开始,rows=5当前返回5条记录,第二页就是变化start这个值为5就可以了。
        params.set("start", 0);
        params.set("rows", Integer.MAX_VALUE);

        // 排序,如果按照id排序,那么将score desc 改成 id desc(or asc)
        // params.set("sort", "score desc");
        params.set("sort", "id asc");

        // 返回信息*为全部,这里是全部加上score,如果不加下面就不能使用score
        params.set("fl", "*,score");

        QueryResponse response = null;
        try {
            response = server.query(params);
        } catch (SolrServerException e) {
            e.printStackTrace();
        }

        if(response!=null){
            System.out.println("Search Results: ");
            SolrDocumentList list = response.getResults();
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        }
    }

    public static void main(String[] args) {
        init();
        //testIndexUser();
        testQueryAll();
    }
}

如果在数据库中添加一条数据,但是Solr索引中没有index这条数据,就查不到,所以一般在使用Solr检索数据库里的内容时,都是先插入数据库,再在Solr中index这条数据,使用Solr的模糊查询或是分词功能来检索数据库里的内容。

DIH增量从MYSQL数据库导入数据
已经学会了如何全量导入MySQL的数据,全量导入在数据量大的时候代价非常大,一般来说都会适用增量的方式来导入数据,下面介绍如何增量导入MYSQL数据库中的数据,以及如何设置定时来做。

1)数据库表的更改

前面已经创建好了一个User的表,这里为了能够进行增量导入,需要新增一个字段updateTime,类型为timestamp,默认值为CURRENT_TIMESTAMP。

有了这样一个字段,Solr才能判断增量导入的时候,哪些数据是新的。

因为Solr本身有一个默认值last_index_time,记录最后一次做full import或者是delta import(增量导入)的时间,这个值存储在文件conf目录的dataimport.properties文件中。

2)data-config.xml中必要属性的设置

transformer 格式转化:HTMLStripTransformer 索引中忽略HTML标签

query:查询数据库表符合记录数据

deltaQuery:增量索引查询主键ID  注意这个只能返回ID字段

deltaImportQuery:增量索引查询导入的数据

deletedPkQuery:增量索引删除主键ID查询 注意这个只能返回ID字段

有关“query”,“deltaImportQuery”, “deltaQuery”的解释,引用官网说明,如下所示:
The query gives the data needed to populate fields of the Solr document in
full-import
The deltaImportQuery gives the data needed to populate fields when running a
delta-import
The deltaQuery gives the primary keys of the current entity which have changes
since the last index time

如果需要关联子表查询,可能需要用到parentDeltaQuery

The
parentDeltaQuery uses the changed rows of the current table (fetched with
deltaQuery) to give the changed rows in theparent table. This is necessary
because whenever a row in the child table changes, we need to re-generate the
document which has that
field.

更多说明看DeltaImportHandler的说明文档。

针对User表,data-config.xml文件的配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
    <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/mybatis" user="root" password="luxx" batchSize="-1" />
  <document name="testDoc">
        <entity name="user" pk="id"
                query="select * from user"
                deltaImportQuery="select * from user where id=‘${dih.delta.id}‘"
                deltaQuery="select id from user where updateTime> ‘${dataimporter.last_index_time}‘">
            <field column="id" name="id"/>
           <field column="userName" name="userName"/>
            <field column="userAge" name="userAge"/>
            <field column="userAddress" name="userAddress"/>
<field column="updateTime" name="updateTime"/>
     </entity>
  </document>
</dataConfig>

增量索引的原理是从数据库中根据deltaQuery指定的SQL语句查询出所有需要增量导入的数据的ID号。

然后根据deltaImportQuery指定的SQL语句返回所有这些ID的数据,即为这次增量导入所要处理的数据。

核心思想是:通过内置变量“${dih.delta.id}”和 “${dataimporter.last_index_time}”来记录本次要索引的id和最近一次索引的时间。

注意:刚新加上的updateTime字段也要在field属性中配置,同时也要在schema.xml文件中配置:

<field name="updateTime" type="date" indexed="true" stored="true" />

如果业务中还有删除操作,可以在数据库中加一个isDeleted字段来表明该条数据是否已经被删除,这时候Solr在更新index的时候,可以根据这个字段来更新哪些已经删除了的记录的索引。

这时候需要在dataConfig.xml中添加:

query="select * from user where isDeleted=0"
deltaImportQuery="select * from user where id=‘${dih.delta.id}‘"
deltaQuery="select id from user where updateTime> ‘${dataimporter.last_index_time}‘ and isDeleted=0"
deletedPkQuery="select id from user where isDeleted=1"

这时候Solr进行增量索引的时候,就会删除数据库中isDeleted=1的数据的索引。

测试增量导入

如果User表里有数据,可以先清空以前的测试数据(因为加的updateTime没有值),用我的Mybatis测试程序添加一个User,数据库会以当前时间赋值给该字段。在Solr中使用Query查询所有没有查询到该值,使用dataimport?command=delta-import增量导入,再次查询所有就可以查询到刚刚插入到MySQL的值。

设置增量导入为定时执行的任务

可以用Windows计划任务,或者Linux的Cron来定期访问增量导入的连接来完成定时增量导入的功能,这其实也是可以的,而且应该没什么问题。

但是更方便,更加与Solr本身集成度高的是利用其自身的定时增量导入功能。

1、下载apache-solr-dataimportscheduler-1.0.jar放到\solr-webapp\webapp\WEB-INF\lib目录下:
下载地址:http://code.google.com/p/solr-dataimport-scheduler/downloads/list
也可以到百度云盘下载:http://pan.baidu.com/s/1dDw0MRn

注意:apache-solr-dataimportscheduler-1.0.jar有bug,参考:http://www.denghuafeng.com/post-242.html

2、修改solr的WEB-INF目录下面的web.xml文件:
为<web-app>元素添加一个子元素

<listener>
        <listener-class>
    org.apache.solr.handler.dataimport.scheduler.ApplicationListener
        </listener-class>
    </listener>

3、新建配置文件dataimport.properties:

在SOLR_HOME\solr目录下面新建一个目录conf(注意不是SOLR_HOME\solr\collection1下面的conf),然后用解压文件打开apache-solr-dataimportscheduler-1.0.jar文件,将里面的dataimport.properties文件拷贝过来,进行修改,下面是最终我的自动定时更新配置文件内容:

#################################################
#                                               #
#       dataimport scheduler properties         #
#                                               #
#################################################

#  to sync or not to sync
#  1 - active; anything else - inactive
syncEnabled=1

#  which cores to schedule
#  in a multi-core environment you can decide which cores you want syncronized
#  leave empty or comment it out if using single-core deployment
#  syncCores=game,resource
syncCores=collection1

#  solr server name or IP address
#  [defaults to localhost if empty]
server=localhost

#  solr server port
#  [defaults to 80 if empty]
port=8983

#  application name/context
#  [defaults to current ServletContextListener‘s context (app) name]
webapp=solr

#  URLparams [mandatory]
#  remainder of URL
#http://localhost:8983/solr/collection1/dataimport?command=delta-import&clean=false&commit=true
params=/dataimport?command=delta-import&clean=false&commit=true

#  schedule interval
#  number of minutes between two runs
#  [defaults to 30 if empty]
interval=1

#  重做索引的时间间隔,单位分钟,默认7200,即1天;
#  为空,为0,或者注释掉:表示永不重做索引
# reBuildIndexInterval=2

#  重做索引的参数
reBuildIndexParams=/dataimport?command=full-import&clean=true&commit=true

#  重做索引时间间隔的计时开始时间,第一次真正执行的时间=reBuildIndexBeginTime+reBuildIndexInterval*60*1000;
#  两种格式:2012-04-11 03:10:00 或者  03:10:00,后一种会自动补全日期部分为服务启动时的日期
reBuildIndexBeginTime=03:10:00

这里为了做测试每1分钟就进行一次增量索引,同时disable了full-import全量索引。

4、测试

在数据库中插入一条数据,在Solr Query中查询,刚开始查不到,Solr进行一次增量索引后就可以查询到了。

一般来说要在你的项目中引入Solr需要考虑以下几点:
1、数据更新频率:每天数据增量有多大,及时更新还是定时更新
2、数据总量:数据要保存多长时间
3、一致性要求:期望多长时间内看到更新的数据,最长允许多长时间延迟
4、数据特点:数据源包括哪些,平均单条记录大小
5、业务特点:有哪些排序要求,检索条件
6、资源复用:已有的硬件配置是怎样的,是否有升级计划

参考:

http://wiki.apache.org/solr/DataImportHandler

http://www.denghuafeng.com/post-242.html

时间: 2024-07-31 14:33:13

使用Solr索引MySQL数据的相关文章

使用sphinx索引mysql数据

数据库表如下 mysql> select * from tb_account; +----+-------+------+ | id | name | age | +----+-------+------+ | 1 | ciaos | 3 | | 2 | stone | 6 | +----+-------+------+ 安装sphinx yum install sphinx libsphinxclient-devel 配置sphinx代替mysql全文索引(/etc/sphinx/sphinx

solr添加mysql数据

http://www.cnblogs.com/luxiaoxun/p/4442770.html 随便沾上遇到的一个问题:sorry, no dataimport-handler defined!,在data-config.xml.schema.xml都正确且jar文件也添加了的情况下 <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler

Solr索引数据

一般来说,索引是系统地排列文档或(其他实体).索引使用户能够在文档中快速地查找信息. 索引集合,解析和存储文档. 索引是为了在查找所需文档时提高搜索查询的速度和性能. 在Apache Solr中的索引 在Apache Solr中,我们可以索引(添加,删除,修改)各种文档格式,如xml,csv,pdf等.可以通过几种方式向Solr索引添加数据.在本章中,将讨论创建索引的几个方法 - 使用Solr Web界面. 使用任何客户端API(如Java,Python等). 使用提交工具. 在本章中,将讨论如

Solr与Mysql简单集成

Solr与Mysql数据库的集成,实现全量索引.增量索引的创建. 基本原理很简单:在Solr项目中注册solr的DataImportHandler并配置Mysql数据源以及数据查询sql语句.当我们通过Solr后台控制页面或者直接访问某个地址(后面给出),Solr就会调用DataImportHandler,连接数据库,根据sql语句查询数据,创建索引. 示例solr版本:solr4.3.1 约定Solr的安装目录,如E:\environment\solr-4.3.1为solr-home.  1.

solr5.5.4 增量索引 自动同步mysql数据

前言:之前测试了solr好几个版本都没有成功,solr比较好下载的版本5.0,5.5,6.6.solr6.6结合tomcat8做自动同步mysql数据一直报错,然后果断测试5.5版本的,成功了. 环境:windows10, jdk1.8,tomcat8,solr5.5.4 实现功能:通过前端输入关键字查询,同时查询多表多字段.当数据库mysql添加或者更新数据的时候,数据自动更新到solr引擎中. 正文: 第一步:下载solr 1.solr5.5下载:http://apache.fayea.co

Solr配置导入MySQL数据

1. 编写配置文件 1)编写data-config-comment.xml,此文件用于描述如何查询MySQL数据,如何将数据变换导入索引. 假设有一个数据库叫mooc,其中有个表叫comment,代表学生的评论 其中: entity对应MySQL数据库表中的一行 query对应全库导入的SQL查询 queryImportQuery 对应增量导入的SQL查询 deltaQuery对应增量导入获取最新修改的行ID,这些ID用于queryImportQuery,SQL的含义中 DATE(updatet

solr的DIH操作同步mysql数据

1.创建MySQL数据 CREATE TABLE `city` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '城市编号', `province_id` INT(10) UNSIGNED NOT NULL COMMENT '省份编号', `city_name` VARCHAR(25) NULL DEFAULT NULL COMMENT '城市名称', `description` VARCHAR(25) NULL DEFAULT N

[转][solr] - 索引数据删除

删除solr索引数据,使用XML有两种写法: 1) <delete><id>1</id></delete> <commit/> 2) <delete><query>id:1</query></delete> <commit/> 删除所有索引,这样写就可以了: <delete><query>*:*</query></delete> <c

[solr] - 索引数据删除

删除solr索引数据,使用XML有两种写法: 1) <delete><id>1</id></delete> <commit/> 2) <delete><query>id:1</query></delete> <commit/> 删除所有索引,这样写就可以了: <delete><query>*:*</query></delete> <c