[在此处输入文章标题]
参考博客:
基础环境搭建
solr版本5.5.5:
一、solr5.5.5可以独立部署,使用默认的Jetty启动
1、准备条件:
环境:JDK需要1.7以上,最好是1.8
下载软件包:
使用清华大学的镜像包:
命令:curl
或者wget
2、解压:
tar -zxvf solr-5.5.5.tgz
3、启动服务器:
bin/solr start
4、验证服务是否启动:
在浏览器中输入:http://IP:8983/solr/ 端口默认是8983 要想修改的话,启动的时候加上参数 -p 8983
5、创建core:
bin/solr create -c mycore
bin/solr delete -c testcore -------删除已创建的core
5、添加中文分词器:
这里采用的是IK分词器,添加分词器是在刚刚创建的core中添加:
位置:${PATH}\server\solr\mycore\conf\managed-schema
添加下面的内容:
<!-- 中文分词 -->
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index" useSmart="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" useSmart="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
并且把jar包添加到:(注意这里的jar一定要版本对应)
${PATH}\server\solr-webapp\webapp\WEB-INF\lib 目录下
验证IK是否安装成功。没有安装成功的话会提示mycore 的core有问题。也可以查看solr的日志。
重启服务器:
bin/solr restart -p 8983 注意重启要指定端口要不然报错
然后看看分词效果:
效果还是不错的。
建立数据库连接并对数据表字段建索引分词
基础说明参考
6、copy一个oracle驱动包到E:\solr\solr-5.5.5\server\solr-webapp\webapp\WEB-INF\lib下,
并在E:\solr\solr-5.5.5\server\solr\liukuncore\conf (liukuncor为我自己新建的一个core)下创建data-config.xml文件,添加内容如下:
<dataConfig>
<dataSource name="testSource1" driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@192.168.4.229:1521:orcl" password="hermes" user="hermes_rc" />
<document>
<entity name="goods1" pk="BID" transformer="DateFormatTransformer" dataSource="testSource1"
query="select id,name,url,price,to_date(to_char(addtime,'yyyy-MM-dd HH24:mi:ss'),'yyyy-MM-dd HH24:mi:ss') addtime from lksolrtest"
deltaQuery="select id BID from lksolrtest where to_char(addtime,'yyyy-MM-dd HH24:mi:ss')>'${dataimporter.last_index_time}'"
deltaImportQuery="select id,name,url,price,to_date(to_char(addtime,'yyyy-MM-dd HH24:mi:ss'),'yyyy-MM-dd HH24:mi:ss') addtime from lksolrtest where id = '${dataimporter.delta.BID}'">
<field column="BID" name="id"/>
<field column="price" name="price" />
<field column="name" name="name" />
<field column="url" name="url" />
<field column="addtime" name="addtime" dateTimeFormat="yyyy-MM-dd HH24:mi:ss" />
</entity>
</document>
</dataConfig>
有点乱,在文本中如图所示:
这里面有几点需要注意的地方:
(1) .pk尽量使用deltaQuery中查询出的主键重命名后的名称,否则会有问题(索引建成功,查询不到内容)
(2) .${dataimporter.last_index_time}代表上次创建完索引的时间,是一个字符串,这个值可以在E:\solr\solr-5.5.5\server\solr\liukuncore\conf\dataimport.properties文件中看到
(3) .${dataimporter.delta.BID}是deltaQuery中查询到的主键值
(4) dateTimeFormat="yyyy-MM-dd HH24:mi:ss"是对数据库中日期格式的转换(转成solr中的日期格式)
7、添加solr-dataimporthandler-5.5.5.jar、solr-dataimporthandler-extras-5.5.5.jar和
mydataimportscheduler.jar三个到E:\solr\solr-5.5.5\server\solr-webapp\webapp\WEB-INF\lib下
并在E:\solr\solr-5.5.5\server\solr\liukuncore\conf\solrconfig.xml对应位置添加
<lib dir="./lib" regex=".*\.jar" />
<requestHandler name="/dataimport" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
接着注释掉下面的内容,防止id默认为String类型
<!--
<searchComponent name="elevator" class="solr.QueryElevationComponent" >
<str name="queryFieldType">string</str>
<str name="config-file">elevate.xml</str>
</searchComponent>
-->
8、在E:\solr\solr-5.5.5\server\solr\liukuncore\conf\managed-schema文件中定义与数据库对应的字段变量
<field name="id" type="int" indexed="true" stored="true" required="true" multiValued="false" />
<field name="name" type = "text_ik" indexed="true" stored="true" />
<field name="price" type = "float" indexed="true" stored="true" />
<field name="url" type = "text_ik" indexed="true" stored="true" />
<field name="addtime" type = "date" indexed="true" stored="true" />
<uniqueKey>id</uniqueKey>
9、E:\solr\solr-5.5.5\server\solr\下创建文件夹conf,并新建文件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=liukuncore,liukuncore1
syncCores=liukuncore
# 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
# URL params [mandatory]
# remainder of URL
#params=/deltaimport?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=7200
# 重做索引的参数
#reBuildIndexParams=/deltaimport?command=full-import&clean=true&commit=true
reBuildIndexParams=/dataimport?command=full-import&clean=true&commit=true
# 重做索引时间间隔的计时开始时间,第一次真正执行的时间#=reBuildIndexBeginTime+reBuildIndexInterval*60*1000;
# 两种格式:2012-04-11 03:10:00 或者 03:10:00,后一种会自动补全日期部分为服务启动时的日期
reBuildIndexBeginTime=18:50:00
10、在E:\solr\solr-5.5.5\server\solr-webapp\webapp\WEB-INF\web.xml文件中添加监听器
<listener>
<listener-class>
org.apache.solr.handler.dataimport.scheduler.ApplicationListener
</listener-class>
</listener>
到此数据库和定时增量更新索引配置的东西已全部完成
多表关联定时更新索引
1. 多表关联索引说明以及场景
上面说到单表索引定时增量更新是针对一张表的数据发生变化的时候更新或者增量添加索引,对于多表而言类似(具体需求为人口库法人库后台检索),多表关联可以理解为用一张主表去关联多个子表,当主表或者子表中的数据发生变化(即数据更改或者数据添加---这里先不做删除,因为删除需要表中有一个字段来表示数据是否为删除状态),需要对索引进行更新。
这里存在两种情况:1.数据修改;2.数据增加。---(这两者都需要表中存在更新时间字段)。 数据修改是由于solr内部的实现机制,当数据发生修改时,我们需要更新修改这部分数据的索引,实质上是直接生成新的索引,在solr内部生成索引时需要指定一个主键id来表示索引的唯一,当下一次生成一个重复的索引时会自动覆盖掉上次生成的索引,保证索引出的数据与数据库数据相同。
数据增加指主表增加了数据或者其子表数据增加再或者两张表数据同时增加,这时需要生成新的索引(不生成新索引,新添加的数据查询不到),下面提供两种方式来生成。
2. 主要配置文件data-config.xml
配置文件内容如下:
<dataConfig>
<dataSource name="testSource1" driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@192.168.4.229:1521:orcl" password="hermes" user="hermes_rc" />
<document>
<entity name="goods3" pk="BID" dataSource="testSource1"
query="select id BID,name,url,price from lksolrtest"
deltaQuery="select id BID from lksolrtest where to_char(addtime,'yyyy-MM-dd HH24:mi:ss')>'${dataimporter.last_index_time}'"
deltaImportQuery="select id BID,name,url,price from lksolrtest where id = '${dataimporter.delta.BID}'">
<field column="BID" name="id"/>
<field column="name" name="name" />
<field column="url" name="url" />
<field column="price" name="price" />
<entity name="goods3_son1" pk="SID"
query="select id SID,address,produce_man,telephone from lksolrtest1 where id = '${goods3.BID}'"
deltaQuery="select id SID from lksolrtest1 where to_char(addtime,'yyyy-MM-dd HH24:mi:ss')>'${dataimporter.last_index_time}'"
parentDeltaQuery="select id BID from lksolrtest where id = '${goods3_son1.SID}'"
>
<field column="address" name="address" />
<field column="produce_man" name="produce_man" />
<field column="telephone" name="telephone" />
</entity>
</entity>
</document>
</dataConfig>
这里主要解释一下增量更新部分的属性:
query是获取全部数据的SQLdeltaImportQuery是获取增量数据时使用的SQLdeltaQuery是获取增量pk的SQLparentDeltaQuery是获取父Entity的pk的SQL
Full Import工作原理:执行本Entity的Query,获取所有数据;针对每个行数据Row,获取pk,组装子Entity的Query;执行子Entity的Query,获取子Entity的数据。Delta Import工作原理:查找子Entity,直到没有为止;执行Entity的deltaQuery,获取变化数据的pk;合并子Entity parentDeltaQuery得到的pk;针对每一个pk Row,组装父Entity的parentDeltaQuery;执行parentDeltaQuery,获取父Entity的pk;执行deltaImportQuery,获取自身的数据;如果没有deltaImportQuery,就组装Query限制:子Entity的query必须引用父Entity的pk子Entity的parentDeltaQuery必须引用自己的pk子Entity的parentDeltaQuery必须返回父Entity的pkdeltaImportQuery引用的必须是自己的pk文件索引创建
文件索引创建未能在界面上成功操作,是通过程序创建,查询结果可以在界面看到,也可以通过程序实现。
1. 创建一个自定义的core--------怎样创建在上面已经提到过
2. 在新生成的core/conf/managed-schema文件中添加IK分词器,
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index" useSmart="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" useSmart="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
并将
<dynamicField name="attr_*" type="text_general" indexed="true" stored="true" multiValued="true"/>中的type改为text_ik,
3. 程序创建文件索引并查询
package com.boco.lk;
import java.io.File;
import java.io.IOException;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
public class DocumentSolr {
private static String URL = "http://localhost:8983/solr/liukuncore3";//指定core的访问路径
/**
* 创建索引方法
*/
public static void createIndex(){
HttpSolrClient client = null;
try {
client = new HttpSolrClient(URL);
ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update/extract");
up.addFile(new File("E:\\solr文档--刘坤\\solr-word.pdf"),"application/pdf");
up.setParam("literal.id", "E:\\solr文档--刘坤\\solr-word.pdf");
up.setParam("fmap.content", "attr_test");//attr_*,只要是以attr_开头即可
up.setParam("fmap.content_type", "documentFormat");//这个content_type在managed-schema文件中有,此行意思是给content_type重命名
up.setAction(AbstractUpdateRequest.ACTION.COMMIT,true,true);
client.request(up);
client.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void queryIndex(){
HttpSolrClient client = null;
try {
client = new HttpSolrClient(URL);
SolrQuery query = new SolrQuery();
query.setParam("q", "*:*");
// query.setParam("df", "attr_content");
// query.setParam("fl","id","attr_content","documentFormat");
QueryResponse rsp = client.query(query);
SolrDocumentList results = rsp.getResults();
System.out.println("查询到记录:"+results.getNumFound()+"条");
for (SolrDocument solrDocument : results) {
System.out.println(solrDocument.getFieldNames());
System.out.println(solrDocument.get("id"));
System.out.println(solrDocument.get("attr_test"));
System.out.println(solrDocument.get("documentFormat"));
System.out.println("**********************");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void deletePlan(String id) {
HttpSolrClient server = null;
try {
server = new HttpSolrClient(URL);
server.deleteById(id);
server.commit();
} catch (SolrServerException | IOException e) {
e.printStackTrace();
} finally {
try {
server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
deletePlan("E:\\solr文档--刘坤\\solr-word.pdf");
createIndex();
queryIndex();
}
}