Apache Solr 是一个开源的搜索服务器,本文介绍一些入门的基础知识,本来想直接写solrdih(dataImportHandler)组件的,但发现有些内容还是会涉及到solr的基础知识,因此也一起写了。
Solr的资源下载可以直接去http://lucene.apache.org/solr/,https://archive.apache.org/dist/lucene/solr/(历史版本)
本文使用3.5版本solr,从wiki上看(http://wiki.apache.org/solr/DataImportHandler),dih组件可能从1.3版本就开始有了。
Solr的目录介绍:
example/solr:该目录是一个包含了默认配置信息的Solr的home目录。
所谓的Solr home目录实际上是一个运行的Solr实例所对应的配置和数据(Lucene索引)。
在example/solr/conf目录下,我们要配置要索引的字段信息,本文会以索引书籍的数据来当做例子。首先我们要配置一个中文分词器,所谓的分词,简单的理解就是将一句完整的话切割成多个词,例如将静消消的博主萌哒哒的来切割成静/消消/的/博主/萌/哒哒/的/来,本文采用的中文分词为ik分词器。需要在schema.xml中配置相应的分词器,并将ik分词器的jar包导入到${solrhome}/contrib/extraction/lib目录下(由solr的默认配置文件solrconfig.xml,在${solrhome}/example/solr/conf目录下,可以观察到solr默认会导入一些目录的jar包文件,如下图所配置):
导入jar包后,在${solrhome}/example/solr/conf/schema.xml中即可配置ik分词器,如下配置:
<!--最好配置在types标签的下面-->
<types>
<!-- The StrField type is not analyzed, but indexed/stored verbatim. -->
<!--ik分词-->
<fieldType name="text_ik" class="solr.TextField">
- <analyzer type="index">
<charFilter class="solr.HTMLStripCharFilterFactory" />
<tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" useSmart="true" />
</analyzer>
- <analyzer type="query">
<charFilter class="solr.HTMLStripCharFilterFactory" />
<tokenizer class="org.wltea.analyzer.solr.IKTokenizerFactory" useSmart="true" />
</analyzer>
</fieldType>
- <fieldType name="text_cjk" class="solr.TextField">
- <analyzer type="index">
<tokenizer class="solr.CJKTokenizerFactory" />
</analyzer>
- <analyzer type="query">
<tokenizer class="solr.CJKTokenizerFactory" />
</analyzer>
</fieldType>
设定好分词器后,我们就可以在solr的网页控制台先观察一下分词效果了,正常配置分词的话,分词效果会如下所示:
配置成功后,solr的初始配置就告一段落,下面有请我们的主角dih出场(此处应该有掌声):
Solr dih是提供一种直接从数据库(常用),实现增量(可自动增量)和全量导入索引的一种辅助工具,同时支持多数据库源。下面来看dih的配置:
首先需要在solrconfig.xml中配置dih,同时需要将数据库的jar包也放到${solrhome}/contrib/extraction/lib目录下
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<!--以下的配置文件是数据库相关配置,放在solrconfig.xml同一目录下即可->
<str name="config">solr-data-config.xml</str>
</lst>
</requestHandler>
数据库字段配置,我们要先在solr schema.xml配置数据库字段对应的索引字段,本文中已索引书籍的字段为例子:
<field name="book_name" type="text_ik" indexed="true" stored="true"/>
<field name="book_publisher" type="text_ik" indexed="true" stored="true"/>
<field name="book_keyword" type="text_ik" indexed="true" stored="true"/>
<field name="book_summary" type="text_ik" indexed="true" stored="true"/>
<field name="book_isbn" type="string" indexed="true" stored="true"/>
<field name="book_publish_year" type="string" indexed="true" stored="true"/>
<field name="book_publish_month" type="string" indexed="true" stored="true"/>
<field name="book_price" type="float" indexed="true" stored="true"/>
<field name="book_author" type="string" indexed="true" stored="true"/>
配置完书籍的solr schema.xml,我们要配置前文提到的数据库配置文件(solr-data-config.xml),使数据库中的数据和solr索引对应:
<dataConfig>
<dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/bookdata"
user="root" password="root"/>
<document>
<entity name="book" pk="id" query="select * from book_detail_bak limit
${dataimporter.request.length} offset ${dataimporter.request.offset}"
deltaImportQuery="select * from book_detail_bak where id='${dih.delta.id}'"
deltaQuery="select id from book_detail_bak where LAST_MODIFIED_TIME >
'${dih.request.lasttime}'"
>
<field name="book_name" column="bookname"/>
<field name="book_publisher" column="PUBLISHER" />
<field name="book_isbn" column="ISBN" />
<field name="book_keyword" column="keyword"/>
<field name="book_summary" column="CONTENTSUMMARY"/>
<field name="book_publish_year" column="PUBLISHINGYEAR"/>
<field name="book_publish_month" column="PUBLISHINGMONTH"/>
<field name="book_price" column="BOOKPRICE"/>
<field name="book_author" column="author"/>
</entity>
</document>
</dataConfig>
当所有的配置完成后,即可先启用全量导入,solr dih的全量导入在数据量非常大的情况下得用分批导入,如:
http://localhost:8983/solr/dataimport?command=full-import&commit=true&clean=false&offset=0&length=10000
//注意这里的clean=false必须加上,默认为true,作用用来告诉solr每次全量导入不删除以前创建的索引
http://localhost:8983/solr/dataimport?command=full-import&commit=true&clean=false&offset=10000&length=10000
因此solr dih的全量导入在一些情况下可能还不太方便,但大部分情况下都可满足普通的应用,而增量导入,这里solr dih做的还是比较好的,甚至有自动增量导入的实现(其实自动增量导入,也是使用定时器完成的)
注意事项:
前文提到的数据库配置文件(solr-data-config.xml)中的:
<entity name="book" pk="id" query="select * from book_detail limit ${dataimporter.request.length} offset ${dataimporter.request.offset}"
deltaImportQuery="select * from book_detail_bak where id='${dih.delta.id}'"
deltaQuery="select id from book_detail_bak where LAST_MODIFIED_TIME > '${dih.request.lasttime}'"
>
pk属性在增量导入时必须加上,并指定为数据表中id
增量导入时有一个技巧,那么就是可以在地址栏手动指定增量更新的时间,如下:
http://127.0.0.1:8983/solr/dataimport?command=delta-import&commit=true&lasttime=20150101