开发者社区> lhyxcxy> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

solr 从数据库导入数据,全量索引和增量索引

简介: 首先说一下是从mysql数据库导入数据 这里使用的是mysql测试。 1、先在mysql中建一个表:solr_test     2、插入几条测试数据:   3、用记事本打solrconfig.xml文件,在solrhome文件夹中。E:\solrhome\mycore\conf\solrconfig.xml (solrhome文件
+关注继续查看

首先说一下是从mysql数据库导入数据

这里使用的是mysql测试。

1、先在mysql中建一个表:solr_test

 

 

2、插入几条测试数据:

 

3、用记事本打solrconfig.xml文件,在solrhome文件夹中。E:\solrhome\mycore\conf\solrconfig.xml

(solrhome文件夹是什么,参见:http://www.cnblogs.com/HD/p/3977799.html)

加入这个节点:

    <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
        <lst name="defaults">
            <str name="config">data-config.xml</str>
        </lst>
    </requestHandler>

 

4、新建一个data-config.xml文件,与solrconfig.xml同一个目录下。内容为

复制代码
<dataConfig>
    <dataSource type="JdbcDataSource"
              driver="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost/test"
              user="root"
              password="root" />
    <document>
        <entity name="solr_test" transformer="DateFormatTransformer"
            query="SELECT id, subject, content, last_update_time FROM solr_test WHERE id >= ${dataimporter.request.id}">
            <field column='last_update_time' dateTimeFormat='yyyy-MM-dd HH:mm:ss' />
        </entity>
    </document>
</dataConfig>
复制代码

说明:这里使用了一个${dataimporter.request.id},这个是参数,后面在做数据导入时,会使用到,以此条件为基准读数据。

 

5、复制解压出的solr jar包solr-dataimporthandler-4.10.0.jar和solr-dataimporthandler-extras-4.10.0.jar到tomcat solr webapp的WEB-INF\lib目录下。

当然,也包括mysql的jdbc jar包:mysql-connector-java-5.1.7-bin.jar

(还有一种方法是在solrconfig.xml中加入lib节点,然后把jar包放到solrhome下,这样可以不在WEB-INF\lib中加入jar包)

 

6、用记事本打开schema.xml,在在solrhome文件夹中(同第3点)。内容为:

复制代码
<?xml version="1.0" ?>
<schema name="my core" version="1.1">

    <fieldtype name="string"  class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="text_cn" class="solr.TextField">
        <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer" />
        <analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer" />
    </fieldType>
    
    <!-- general -->
    <field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
    <field name="subject" type="text_cn" indexed="true" stored="true" />
    <field name="content" type="text_cn" indexed="true" stored="true" />
    <field name="last_update_time" type="date" indexed="true" stored="true" />
    <field name="_version_" type="long" indexed="true" stored="true"/>

     <!-- field to use to determine and enforce document uniqueness. -->
     <uniqueKey>id</uniqueKey>

     <!-- field for the QueryParser to use when an explicit fieldname is absent -->
     <defaultSearchField>subject</defaultSearchField>

     <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
     <solrQueryParser defaultOperator="OR"/>
</schema>
复制代码

 

7、打开solr web:

说明:

Custom Parameters填入id=1,这是在第4点中设置的参数。

Clean选项,是指是否删除未匹配到的数据。也就是在数据库select结果中没有,而solr索引库中存在,则删除。

也可以使用这个地址直接访问:

http://localhost:8899/solr/mycore/dataimport?command=full-import&clean=true&commit=true&wt=json&indent=true&entity=solr_test&verbose=false&optimize=false&debug=false&id=1

将返回结果:

配置好后,之后我们只需要使用这个url地址,就可以不段的去导入数据做索引了。(就这么简单)

 

8、测试查询:


 

 

当然,dataimport可以加入参数命令,让其重新加载data-config.xml

http://localhost:8899/solr/#/mycore/dataimport/command=reload-config


下面全量索引和增量索引的配置区别,注意和上面不是同一个工程(首先全量索引会把数据库中所有数据进行索引的更新,增量索引只更新数据库中增删改查过的)要使用增量索引,数据库中要有一个标识字段来表示数据的变化,我们可以使用时间戳来表示,数据更新时时间戳也更新,这样,solr通过比较时间戳的变化来增量更新索引。

 

1.修改multicore/new_core/conf/solrconfig.xml文件(上篇提到过的),在里面新增

Xml代码  收藏代码
  1. <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">  
  2.      <lst name="defaults">  
  3.      <str name="config">data-config.xml</str>  
  4.      </lst>   
  5. </requestHandler>   
  6. <requestHandler name="/deltaimport" class="org.apache.solr.handler.dataimport.DataImportHandler">  
  7.     <lst name="defaults">  
  8.         <str name="config">delta-data-config.xml</str>  
  9.     </lst>  
  10. </requestHandler>  

 其中第一段是专门做全量索引的,第二段做增量索引(主要是靠DataImportHandler类实现)

 

2.新增multicore/new_core/conf/data-config.xml文件

Xml代码  收藏代码
  1. <dataConfig>  
  2.     <dataSource name="jdbc" driver="com.mysql.jdbc.Driver"  
  3.         url="jdbc:mysql://192.168.0.81:3306/new_mall?zeroDateTimeBehavior=convertToNull&amp;characterEncoding=utf8&amp;useUnicode=true"  
  4.         user="root" password="HyS_Db@2014"/>  
  5.     <document name="mall_goods">  
  6.         <entity name="MallGoods" pk="id"  
  7.                 query="select * from mall_goods limit ${dataimporter.request.length} offset ${dataimporter.request.offset}"  
  8.                 transformer="RegexTransformer">  
  9.             <field column="goods_id" name="id" />  
  10.             <field column="title" name="title" />  
  11.             <field column="subtitle" name="subtitle" />  
  12.             <field column="cover_img_path" name="coverImgPath" />  
  13.             <field column="description" name="description" />  
  14.             <field column="update_date" name="updateDate" />  
  15.         </entity>  
  16.     </document>  
  17. </dataConfig>  

dataSource不用说了,数据源配置来的 

entity文档中的实体配置(注意pk="id" 不能随便改 ,需要和schema.xml中的<uniqueKey>id</uniqueKey>匹配,否则会报“ org.apache.solr.common.SolrException: Document is missing mandatory uniqueKey field: id”)

query 查询语句(可分页)

transformer 暂时不清楚干啥

field定义列名

 

3.新增multicore/new_core/conf/delta-data-config.xml文件

 

Xml代码  收藏代码
  1. <dataConfig>  
  2.     <dataSource name="jdbc" driver="com.mysql.jdbc.Driver"  
  3.         url="jdbc:mysql://192.168.0.81:3306/new_mall?zeroDateTimeBehavior=convertToNull&amp;characterEncoding=utf8&amp;useUnicode=true"  
  4.         user="root" password="HyS_Db@2014"/>  
  5.     <document name="mall_goods">  
  6.         <entity name="MallGoods" pk="id"  
  7.                 query="select * from mall_goods"  
  8.                 deltaImportQuery="select * from mall_goods where goods_id='${dih.delta.id}'"  
  9.                 deltaQuery="select goods_id as id from mall_goods where update_date &gt; '${dih.last_index_time}'"  
  10.                 transformer="RegexTransformer">  
  11.             <field column="goods_id" name="id" />  
  12.             <field column="title" name="title" />  
  13.             <field column="subtitle" name="subtitle" />  
  14.             <field column="cover_img_path" name="coverImgPath" />  
  15.             <field column="description" name="description" />  
  16.             <field column="update_date" name="updateDate" />  
  17.         </entity>  
  18.     </document>  
  19. </dataConfig>  

 

deltaQuery查询出有更改过的id

deltaImportQuery根据id查询 

 

4.修改multicore/new_core/conf/schema.xml文件,定义field索引配置

Xml代码  收藏代码
  1. <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />   
  2. <field name="title" type="text_ansj" indexed="true" stored="true" required="true" multiValued="false"/>  
  3. <field name="subtitle" type="text_ansj" indexed="true" stored="true" required="false" multiValued="false"/>  
  4. <field name="coverImgPath" type="string" indexed="false" stored="true" required="true" multiValued="false" />  
  5. <field name="description" type="text_ansj" indexed="true" stored="true" required="false" multiValued="false"/>  
  6. <field name="updateDate" type="text_ansj" indexed="true" stored="true" required="false" multiValued="false"/>  
  7.       

 注意上面选择一下text_ansj

 

5.solr的war包可能还缺少部分jar包,需要把mysql的jar,以及solr项目中dist目录下的jar包都放到solr的web站点中

 

6.开始运行

全量:http://solr.xxxx.com:8082/new_core/dataimport?command=full-import&commit=true&clean=false&offset=0&length=100000(其中0到100000的数据建立索引)

增量:http://solr.ehaoyao.com:8082/new_core/deltaimport?command=delta-import&entity=MallGoods 

 

entity:是document下面的标签(data-config.xml)。使用这个参数可以有选择的执行一个或多个entity   。使用多个entity参数可以使得多个entity同时运行。如果不选择此参数那么所有的都会被运行。

clean:选择是否要在索引开始构建之前删除之前的索引,默认为true

commit:选择是否在索引完成之后提交。默认为true

optimize:是否在索引完成之后对索引进行优化。默认为true

debug:是否以调试模式运行,适用于交互式开发(interactive development mode)之中。

 

请注意,如果以调试模式运行,那么默认不会自动提交,请加参数“commit=true” 

 

 

注意:在做增量索引的时候

很容易出现deltaQuery has no column to resolve to declared primary key pk='id'这种异常

主要是因为ID" must be used as it is in 'deltaQuery' select statement as "select ID from ..."

(if you different name for ID column in database, then use 'as' keyword in select statement. In my case I had 'studentID' as primary key in student table. So I used it as "select studentID as ID from ..."

--> The same applies to 'deletedPkQuery'

At present its working fine for me. Any updation in database is reflected in Solr as well.

所以,delta-data-config.xml文件需要注意一下pk的值

 

 

 

参考连接:

http://shiyanjun.cn/archives/444.html

http://blog.duteba.com/technology/article/70.htm

http://www.devnote.cn/article/89.html

http://qiaqia26.iteye.com/blog/1004996

http://zzstudy.offcn.com/archives/8104

http://blog.csdn.net/duck_genuine/article/details/5426897 

 

 

 

------------------------------------------------------------------------------------------------------------------------------

最后补充:

有时候需要删除索引数据,可以这样删除

 

http://xxxx/new_core/update/?stream.body=<delete><query>*:*</query></delete>&stream.contentType=text/xml;charset=utf-8&commit=true

 

new_core 表示你要删除哪个核下面的索引


java代码调用增量和全量索引

import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;

import base.util.ConfigUtil;

public class SolrService {
    private static Logger log = Logger.getLogger(SolrService.class);

    private static HttpSolrServer solrServer;

    static {
        solrServer = new HttpSolrServer(ConfigUtil.getValue("solr.url"));
        solrServer.setConnectionTimeout(5000);
    }

    /**
     * 增量/全量建立索引 。
     * 
     * @param delta ture,增量建立索引;false,重建所有索引
     */
    public static void buildIndex(boolean delta) {
        SolrQuery query = new SolrQuery();
        // 指定RequestHandler,默认使用/select
        query.setRequestHandler("/dataimport");

        String command = delta ? "delta-import" : "full-import";
        String clean = delta ? "false" : "true";
        String optimize = delta ? "false" : "true";
        
        query.setParam("command", command)
             .setParam("clean", clean)
             .setParam("commit", "true")
             .setParam("entity", "article")
             .setParam("optimize", optimize);
        try {
            solrServer.query(query);
        } catch (SolrServerException e) {
            log.error("建立索引时遇到错误,delta:" + delta, e);
        }
    }
    
}

相关说明:

主要原理:是利用率每次我们进行import的时候在solr.home的conf下面生成的dataimport.properties文件,此文件里面有最近一次导入的相关信息,如:
我的文件位置为

/root/solr-4.5.1/example/solr/collection1/conf

我的文件内容为

#Mon Dec 09 14:06:03 CST 2013
last_index_time=2013-12-09 14\:06\:00
article.last_index_time=2013-12-09 14\:06\:00

last_index_time是最近一次增量或全量索引的时间,通过比较这个时间和我们数据库表中的update_time列即可得出哪些是之后修改或者添加的。

data-config.xml说明:

  1. query是获取全部数据的SQL
  2. deltaImportQuery是获取增量数据时使用的SQL
  3. deltaQuery是获取主键的SQL

参数说明:

  1. clean:设置建索引前是否删除之前的索引;
  2. commit:设置建索引后是否自动提交;
  3. entity:mysql-data-config.xml entity name中配置的名称,如果配有多个,且这里不指定,所有entity都会被执行;
  4. optimize:设置建索引后是否自动优化。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
将一个数据库表中的数据导入另一个数据库相应表中
语句形式为:      insert into 数据库名.框架名.表名(列名) select (列名) from 数据库名.框架名.表名 where 条件 类似这样写就行了insert into MyEmp.dbo.
604 0
复制数据库表数据到另外一张表
T1->T2:   insert into tc1(name,sex)   select textarea,id from tc   select *from tc1   为了方便显示映射关系: tc表数据复制到tc1上面去 两个表字段可以不一致,只需要保证字段类型对应一致即可(至少可以默认转换) name------ textarea , sex-------- id . 将tc表中的textarea 添加到tc1表中的name字段中,后面字段同理。
349 0
【数据库】表分区
介绍:     分区表在逻辑上是一个表,而物理上是多个表。从用户角度来看,分区表和普通表是一样的。使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性。表分区简单理解就是表还是原先的表,但是根据不同条件分块的把数据存放到不同文件下。
798 0
PostgreSQL快速导入千万条数据
PostgreSQL快速导入千万条数据
0 0
你还不知道什么是数据库的索引吗
在MySQL的官方文档里对于索引的定义是:索引(Index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
0 0
+关注
lhyxcxy
专注于前后端服务器交互,人工智能,NLP领域
文章
问答
文章排行榜
最热
最新
相关电子书
更多
HBase在时间序列数据库中的应用
立即下载
PostgresChina2018_肖斐_PostgreSQL数据库时空引擎Ganos
立即下载
MySQL表和索引优化实战
立即下载