solr的基础和安装
下载地址
http://archive.apache.org/dist/lucene/solr/ 推荐
http://www.apache.org/dyn/closer.lua/lucene/solr/7.7.0/solr-7.7.0.tgz
低版本的安装方法
1,首先有一个solr-4.10.3.zip的文件。解压,dist下有个war文件。
2,复制war,放到tomcat中,启动,解压。
3,将 solr-4.10.3.zip/example/lib/ext 目录下的所有的 jar 包,添加到刚解压出来的 solr 的工程中(\WEB-INF\lib目录下)
4,创建一个 solrhome 。solr-4.10.3.zip 下的/example/solr 目录就是一个 solrhome。复制此目录到D盘改名为solrhome
5,关联 solr 及 solrhome。需要修改 solr 工程的 web.xml 文件
<env-entry> <env-entry-name>solr/home</env-entry-name> <env-entry-value>d:\solrhome</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry>
6,启动 Tomcat
安装ik
1,把IKAnalyzer2012FF_u1.jar 添加到 solr 工程的\WEB-INF\lib 目录下
2,创建WEB-INF/classes文件夹 把扩展词典、停用词词典、配置文件放到 solr 工程的 WEB-INF/classes 目录下
ext_stopword.dic
也
了
仍
从
以
使
则
却
又
及
对
就
并
很
或
把
是
的
着
给
而
被
让
在
还
比
等
当
与
于
但
乃
了
好
mydict.dic
刘中华
高富帅
白富美
IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典--> <entry key="ext_dict">mydict.dic;</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords">ext_stopword.dic</entry> </properties>
3、修改 Solrhome 的 solrhome\collection1\conf\schema.xml 文件,配置一个 FieldType,使用 IKAnalyzer
<fieldType name="text_ik" class="solr.TextField"> <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/> </fieldType>
高版本的安装方法
http://www.cnblogs.com/ITDreamer/p/10661949.html
// cmd 到bin目录 solr start -f 启动
在bin目录下执行bin/solr start 此命令会启动solr应用服务器默认端口为8983,如果想指定端口号启动可以加参数–p例 如:solr start –p 8888. 出现Started Solr server on port 8983. Happy searching! 表示成功
访问http://localhost:8983/solr/ s小写
2. solr常用命令:
solr start –p 端口号 单机版启动solr服务
solr restart –p 端口号 重启solr服务
solr stop –p 端口号关闭solr服务
solr create –c name 创建一个core实例(core概念后面介绍)
创建core
core创建:core的创建方式有很多种一下列出两种比较方便的。
1) 在bin目录下执行solr create –c name,创建一个core,默认创建出来的位置如下图
2) 第二种方式是直接使用AdminUI页面创建一个core
在server/solr 目录下创建core名称 hello
再将 configsets/_default 目录下的conf目录拷贝到 hello 目录下
修改页面上new_core 为刚新建的目录名称hello
ok 了
安装ik
虽然是5.0的ik,但是可是用
解压把 里面的两个jar复制,放到solr-8.0.0\server\solr-webapp\webapp\WEB-INF\lib下
然后再在WEB-INF下创建classes目录,将另外三个关于分词的文件扔里面。
然后再去数据库的目录solr-8.0.0\server\solr\hello\conf\managed-schema文件。添加ik分词器字段。
<!-- ik分词器 --> <fieldType name="text_ik" class="solr.TextField"> <!-- 索引分词器 --> <analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/> <!-- 查询分词器 --> <analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/> </fieldType>
DIH导入索引数据
1. DIH简介:
DIH全称是Data Import Handler 数据导入处理器,顾名思义这是向solr中导入数据的,我们的solr目的就是为了能让我们的应用程序更快的查询出用户想要的数据,而数据存储在应用中的各种地方入xml、pdf、关系数据库中,那么solr首先就要能够获取这些数据并在这些数据中建立索引来达成快速搜索的目的,这里就列举我们最常用的从关系型数据库中向solr导入索引数据。
2 . 配置文件
位置 : solr-8.0.0\server\solr\数据库\conf 下
2个重要的文件,solrconfig.xml (这个是设置连接数据库映射的)和 managed-schema(老版本是schema.xml) 这个是设置solr数据库字段的。
第一步:
在solrconfig.xml 写下面代码
<requestHandler name="/dataimport" class="solr.DataImportHandler"> <lst name="defaults"> <str name="config">db-data-config.xml</str> </lst> </requestHandler>
然后在同级目录创建 db-data-config.xml 文件,里面是配置映射的东东,不用写,去example中复制就行 solr-8.0.0\example\example-DIH\solr\db\conf 下有
db-data-config.xml
(下面这个可以满足增量,全量,删除,等操作。)注意:数据库字段,一定要有一个时间字段来作为增量的标志,还要有一个删除字段,来作为同步删除的标志
<dataConfig> <!-- <dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:${solr.install.dir}/example/example-DIH/hsqldb/ex" user="sa" /> --> <dataSource name="bill" type="JdbcDataSource" driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orcl" user="bill" password="bill2018"/> <document> <entity name="item" pk="ID" query="SELECT ID,ITEM_GOODSID,ITEM_TITLE,ITEM_PRICE,ITEM_IMAGE,ITEM_CATEGORY,ITEM_SELLER,ITEM_BRAND,LAST_MODIFIED from ITEM where IS_DELETE='0'" deltaQuery="select id from item where IS_DELETE='0' AND last_modified > to_date('${dataimporter.last_index_time}' ,'yyyy-mm-dd hh24:mi:ss') " deletedPkQuery="select ID from ITEM where IS_DELETE='1' " deltaImportQuery="select ID,ITEM_GOODSID,ITEM_TITLE,ITEM_PRICE,ITEM_IMAGE,ITEM_CATEGORY,ITEM_SELLER,ITEM_BRAND,LAST_MODIFIED from item where IS_DELETE='0' AND id = '${dih.delta.ID}' "> <field column="ID" name="id" /> <field column="ITEM_GOODSID" name="item_goodsid" /> <field column="ITEM_TITLE" name="item_title" /> <field column="ITEM_PRICE" name="item_price" /> <field column="ITEM_IMAGE" name="item_image" /> <field column="ITEM_CATEGORY" name="item_category" /> <field column="ITEM_SELLER" name="item_seller" /> <field column="ITEM_BRAND" name="item_brand" /> <field column="LAST_MODIFIED" name="last_modified"/> </entity> </document> </dataConfig>
Entity标签默认支持的属性如下:
Name:(必须)唯一的名称,用来区分Entity。
Processor:如果不定义,默认值为SqlEntityProcessor,用于从关系型数据库导入数据。如果从关系型数据库以外的源导入数据,需要指定对应的Processor。
Transformer:应用在此字段上的transformer。
dataSource:Entity对应表或者视图所用的数据源。引用数据源配置的name。
Pk:Entity中的主键,与数据库中的主键不完全对应。该字段可选,用于增量导入(delta-import)。
RootEntity:默认document标签下的Entity标签的该属性为True。如果该层Entity的属性为False。则接下来一层的Entity的该属性为Ture。(嵌套时直到该属性为True)。根Entity每有一条记录满足条件,就会在Solr中创建一个文档(Document)。
onError:可能值为三个,abort,skip和continue。默认值为abort,表示终止导入;skip表示跳过导入错误的Document。Continue表示忽略错误,继续执行导入。
preImportDeltaQuery:在全导入前,如果未定义该属性,则使用“*:*”作为条件Clean索引。如果定义该属性,则使用该属性定义值清除索引。不用或慎用。
postImportDeltaQuery:在全导入后,该属性被用来清理索引<!>(此处意义不明,需要查看源码)。不用或慎用。
当从关系型数据库中导入数据时,默认使用SqlEntityProcessor,由于此Processor所引入的属性如下:
query:(必须),用来查询DB的Sql语句。该语句查询得到该Entity所需要的记录和字段。对于子Entity,需要引用父Entity中的某个字段,以实现表间关联。
DeltaQuery:只在增量导入中使用。该语句提供该Entity中对应表的修改记录的主键值的集合。数据库需要有修改时间的字段,该Sql根据修改时间查询满足条件的记录。
parentDeltaQuery:只在增量导入中有效。该语句使用deltaQuery中得到的主键值集合获得父Entity改变记录的主键值的集合。
deletePkQuery: 只在增量导入中有效。该属性提供数据库中标记为删除记录的主键值。为了实现能够删除记录的同步,需要在数据库每个表中增加字段用来标识该记录需要删除。
deltaImportQuery: 只在增量导入中有效。该属性用于根Entity,如果该属性不存在,DIH会使用尝试使用query属性中的Sql语句生成查询。该属性中可以使用变量${dih.delta.<column_name>}。
query还可以携带参数:比如 select * from item where create_time between to_date( '${dataimporter.request.startTime}' ,'yyyy-mm-dd hh24:mi:ss') and to_date( '${dataimporter.request.endTime}' ,'yyyy-mm-dd hh24:mi:ss')
在managed-schema文件中加上字段
<!-- 基本字段 --> <!-- 商品id --> <field name="item_goodsid" type="long" indexed="true" stored="true"/> <!-- 商品标题 --> <field name="item_title" type="text_ik" indexed="true" stored="true"/> <!-- 商品价格 --> <field name="item_price" type="double" indexed="true" stored="true"/> <!-- 商品图片 --> <field name="item_image" type="string" indexed="false" stored="true" /> <!-- 商品种类 --> <field name="item_category" type="string" indexed="true" stored="true" /> <!-- 商品卖家 --> <field name="item_seller" type="text_ik" indexed="true" stored="true" /> <!-- 商品 品牌 --> <field name="item_brand" type="string" indexed="true" stored="true" /> <!-- 复制域 标题+种类+卖家+品牌 --> <field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/> <copyField source="item_title" dest="item_keywords"/> <copyField source="item_category" dest="item_keywords"/> <copyField source="item_seller" dest="item_keywords"/> <copyField source="item_brand" dest="item_keywords"/> <!-- 动态域 --> <dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />
{ "id": "1", "item_goodsid": 1111, "item_title": "128G的华为p30", "item_price": 3888.8, "item_image": "http://1.jpg", "item_category": "手机", "item_seller": "张三店铺", "item_brand": "华为", "item_spec_size": "3.5mm" }
测试成功之后会在数据库的config文件夹自动创建dataimport.properties
#Thu Apr 18 18:12:49 GMT+08:00 2019 item.last_index_time=2019-04-18 18\:12\:48 last_index_time=2019-04-18 18\:12\:48
估计会报这个错。 重启Solr时报错ClassNotFoundException - DataImportHandler
还有吧对应的数据库的jar包放到lib下。。。。。
使用Solr的DIH工具进行配置完成后,重启Solr后,在Solr Admin UI上报如下错误:
Error loading class 'org.apache.solr.handler.dataimport.DataImportHandler'
排查日志文件:solr_home/server/logs目录下,发现了如下错误。
Caused by: java.lang.ClassNotFoundException: org.apache.solr.handler.dataimport.DataImportHandler
解决这个问题:
org.apache.solr.handler.dataimport.DataImportHandler这个类在这个jar包中,在solr-6.0.1/dist/solr-dataimporthandler-6.0.1.jar
把solr-6.0.1/dist/solr-dataimporthandler-6.0.1.jar复制到solr-6.0.1/server/solr-webapp/webapp/WEB-INF/lib目录下;
再重启就可以了。
query是获取全部数据的SQL
deltaImportQuery是获取增量数据时使用的SQL
deltaQuery是获取pk的SQL
parentDeltaQuery是获取父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的pk
deltaImportQuery引用的必须是自己的pk
数据导入
如果执行全量导入操作,导入前清除索引,导入后提交结果,则发送如下Url请求:
http://localhost:8983/solr/test/dataimport?command=full-import&clean=true&commit=true
如果执行增量导入操作,导入前不清除索引,导入后提交结果,发送url如下:
http://ip:port/[webdir/]数据库名字/dataimport?command=delta-import&clean=false&commit=true
解决东八区问题
我们增量部署的时候,一定要有一个时间字段来区别。solr也会有记录更新时间。但是我发现,记录的时间比当前时间要少8小时,因为solr的格式是UTC。我们是东八区,所以我们要把时间换成我们的时间。
打开bin\solr.in.cmd 找到
REM set SOLR_TIMEZONE=UTC set SOLR_TIMEZONE=GMT+08
REM 是注释的。
然后重启,打开面板,java properties 查看时间格式是否换成功。
定时任务
准备好 定时任务的jar包 solr-dataimportscheduler-1.1.jar 扔到 WEB-INF\lib下
下solrHome文件夹 与数据库文件夹同目录下 创建config文件夹 创建 dataimport.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 # 修改成你所使用的core,我这里是我自定义的core:simple syncCores=test # solr server name or IP address # [defaults to localhost if empty] # 这个一般都是localhost不会变 server=localhost # solr server port # [defaults to 80 if empty] # 安装solr的tomcat端口,如果你使用的是默认的端口,就不用改了,否则改成自己的端口就好了 port=8983 # application name/context # [defaults to current ServletContextListener's context (app) name] # 这里默认不改 webapp=solr # URL params [mandatory] # remainder of URL # 这里改成下面的形式,solr同步数据时请求的链接 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,即5天; # 为空,为0,或者注释掉:表示永不重做索引 #reBuildIndexInterval=7200 # 重做索引的参数 #reBuildIndexParams=/select?qt=/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
然后在web.xml中添加监听器
<listener><listener-class>org.apache.solr.handler.dataimport.scheduler.ApplicationListener</listener-class></listener>
ok。重启就好