solr应用
Solr是apache的顶级开源项目,它是使用java开发 ,基于lucene的全文检索服务器。Solr比lucene提供了更多的查询语句,而且它可扩展、可配置,同时它对lucene的性能进行了优化。Solr和lucene有什么区别呢?
Lucene是一个全文检索引擎工具包,它只是一个jar包,不能独立运行与对外提供服务。
Solr是一个全文检索服务器,它可以单独运行在servlet容器上,可以单独对外提供搜索和索引功能。Solr比lucene在开发全文检索功能方面更快捷、更方便。
那么,Solr是如何实现全文检索的呢?
索引流程:solr客户端(浏览器、java程序)可以向solr服务端发送POST请求,请求内容是包含Field等信息的一个xml文档,通过该文档,solr实现对索引的维护(增删改)。
搜索流程:solr客户端(浏览器、java程序)可以向solr服务端发送GET请求,solr服务器返回一个xml文档。
在使用solr时,先要下载与安装solr(本文使用4.10.3版本),下载地址:http://archive.apache.org/dist/lucene/solr/。其中,Solr和lucene的版本是同步更新的。
Linux下需要下载lucene-4.10.3.tgz,windows下需要下载lucene-4.10.3.zip。
solr运行环境是:
Jdk:1.7及以上 Solr:4.10.3 Mysql:5X Web服务器:tomcat 7
将solr-4.10.3/dist下的solr-4.10.3.war包(为使用方便,将其更名为solr.war)拷贝到tomcat的webapps下,启动tomcat时,该war包会自动解压缩为名称为solr的文件夹,此时,将solr.war包删除。接下来,添加solr的扩展服务包,截图如下(jar包数量较多,部分显示):

接下来,将log4j.properties等配置文件拷贝到如下路径:

接下来,在web.xml中指定solrhome的目录:

<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>E:\tomcat\apache-tomcat-7.0.53-8090\solrhome</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
其中,Solrhome是solr服务运行的主目录,一个solrhome目录里面包含多个solrcore目录,一个solrcore目录里面包含了一个solr实例运行时所需要的配置文件和数据文件。每一个solrcore都可以单独对外提供搜索和索引服务。多个solrcore之间没有关系。solrhome的文件结构:

solrcore的文件结构如下:

在solrcore的conf文件下,找到solrconfig.xml文件,通过里面的lib标签来指定依赖包的地址:
<lib dir="${solr.install.dir:..}/contrib/extraction/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:..}/dist/" regex="solr-cell-\d.*\.jar" />
<lib dir="${solr.install.dir:..}/contrib/clustering/lib/" regex=".*\.jar" />
<lib dir="${solr.install.dir:..}/dist/" regex="solr-clustering-\d.*\.jar" />
<lib dir="${solr.install.dir:..}/contrib/langid/lib/" regex=".*\.jar" />
<lib dir="${solr.install.dir:..}/dist/" regex="solr-langid-\d.*\.jar" />
<lib dir="${solr.install.dir:..}/contrib/velocity/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:..}/dist/" regex="solr-velocity-\d.*\.jar" />
<lib dir="${solr.install.dir:..}/contrib/dataimporthandler/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:..}/contrib/db/lib" regex=".*\.jar" />
里面的“solr.install.dir”表示solrcore的安装目录。
再在solrcore的conf文件下找到schema.xml文件,加入如下配置信息:
<!-- Chinese -->
<fieldType name="text_zh" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"> </analyzer>
</fieldType>
<field name="content_zh" type="text_zh" indexed="true" stored="true"></field> <field name="product_name" type="text_zh" indexed="true" stored="true"></field>
<field name="product_catalog_name" type="text_zh" indexed="true" stored="true"></field>
<field name="product_price" type="float" indexed="true" stored="true"></field>
<field name="product_description" type="text_zh" indexed="true" stored="true"></field> <field name="product" type="text_zh" indexed="true" stored="true" multiValued="true"></field> <copyField source="id" dest="product"/>
<copyField source="product_name" dest="product"/>
<copyField source="product_catalog_name" dest="product"/>
<copyField source="product_price" dest="product"/>
<copyField source="product_description" dest="product"/>
其中,product是测试搜索的数据。
每个SolrCore都有自己的索引文件目录 ,默认在SolrCore目录下的data中。data数据目录下包括了index索引目录 和tlog日志文件目录。如果不想使用默认的目录也可以通过solrConfig.xml更改索引目录 ,如下:
<dataDir>${solr.data.dir:E:/develop/solr/solrhome/solrcore/data}</dataDir>
在solrconfig.xml文件中,有个requestHandler标签,它是一个请求处理器,定义了索引和搜索的访问方式。通过/update维护索引,可以完成索引的添加、修改、删除操作;通过/select搜索索引;通过/dataimport可以导入数据库中的数据。如下:
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
在配置完solr后,启动tomcat,访问solr,界面如下:

一个solr服务器可以配置多个solrcore,这样做的好处有:
(1)在进行solrcloud的时候,必须配置多solrcore。
(2) 每个solrcore之间是独立的,都可以单独对外提供服务;不同的业务模块可以使用不同的solrcore来提供搜索和索引服务。
在使用solr时,要先在schema.xml文件中配置solrcore的一些数据信息,包括Field和FieldType的定义等信息,在solr中,Field和FieldType都需要先定义后使用。
定义Field域
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
Name:指定域的名称
Type:指定域的类型
Indexed:是否索引
Stored:是否存储
Required:是否必须
multiValued:是否多值,比如商品信息中,一个商品有多张图片,一个Field像存储多个值的话,必须将multiValued设置为true。
----------------------------------------------
动态域
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
Name:指定动态域的命名规则
------------------------------------------------
指定唯一键
<uniqueKey>id</uniqueKey>
其中的id是在Field标签中已经定义好的域名,而且该域要设置为required为true。
一个schema.xml文件中必须有且仅有一个唯一键
-----------------------------------------------
复制域
<copyField source="cat" dest="text"/>
Source:要复制的源域的域名
Dest:目标域的域名
由dest指的的目标域,必须设置multiValued为true。
-------------------------------------------------
定义域的类型
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-->
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
Name:指定域类型的名称
Class:指定该域类型对应的solr的类型
Analyzer:指定分析器
Type:index、query,分别指定搜索和索引时的分析器
Tokenizer:指定分词器
Filter:指定过滤器
-------------------------------------------------
使用ikanalyzer进行中文分词
<!-- Chinese -->
<fieldType name="text_zh" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"> </analyzer>
</fieldType>
<field name="content_zh" type="text_zh" indexed="true" stored="true"></field>
我们在java程序中使用solr时,需要使用solrj,这是solr服务器的java客户端。其操作逻辑如下:

接下来通过代码演示操作solr:
package com.itszt.solr; import org.apache.solr.client.solrj.SolrQuery;
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.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test; import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set; /**
* 测试solr
*/
public class TestUpdate {
//products中,product_price的type为text_zh
// //products2中,product_price的type为float
//更换另一个solr-core //测试插入数据
@Test
public void testInsertData() throws IOException, SolrServerException {
HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8090/solr/products2");
SolrInputDocument solrInputDocument = new SolrInputDocument();
solrInputDocument.addField("id","10086");
solrInputDocument.addField("product_name","大红花");
solrInputDocument.addField("product_price","28.89");
solrInputDocument.addField("product_description","这朵大红花就是好好看");
solrServer.add(solrInputDocument);
solrServer.commit();
} //测试更新数据
@Test
public void testUpdateData() throws IOException, SolrServerException {
HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8090/solr/products2");
SolrInputDocument solrInputDocument = new SolrInputDocument();
solrInputDocument.addField("id","10086");
solrInputDocument.addField("product_name","大红花");
solrInputDocument.addField("product_price","28.79");
solrInputDocument.addField("product_description","这朵大红花在加工后就是好好看");
solrServer.add(solrInputDocument);
solrServer.commit();
} //测试删除数据
@Test
public void testDelteData() throws IOException, SolrServerException {
HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8090/solr/products2");
//solrServer.deleteById("10086");
solrServer.deleteByQuery("product:10086");
solrServer.commit();
} //测试查询数据
@Test
public void testQueryDatas() throws SolrServerException {
HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8090/solr/products2");
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("product_name:花儿");
QueryResponse queryResponse = solrServer.query(solrQuery);
SolrDocumentList results = queryResponse.getResults();
for(SolrDocument result:results){
// System.out.println("result = " + result);
Collection<String> fieldNames = result.getFieldNames();
for(String fieldName:fieldNames){
System.out.println(fieldName+" ---> " + result.get(fieldName));
}
}
} //测试查询高亮度显示的数据
@Test
public void testQueryDatasHl() throws SolrServerException {
HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8090/solr/products2"); SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("product_name:家居");
solrQuery.setFields("product_name,product_price");
solrQuery.setFilterQueries("product_price:[10 TO 100]");
solrQuery.setSort("product_price",SolrQuery.ORDER.asc);
solrQuery.setHighlight(true);
solrQuery.set("hl.fl","product_name"); QueryResponse queryResponse = solrServer.query(solrQuery); SolrDocumentList results = queryResponse.getResults();
System.out.println("查询回来的数据量:" + results.size()); for(SolrDocument result:results){
Collection<String> fieldNames = result.getFieldNames();
for(String fieldName:fieldNames){
System.out.println(fieldName+"--->"+result.get(fieldName));
System.out.println("----------------------");
}
} System.out.println("获取高亮数据:");
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
Set<String> keySet1 = highlighting.keySet();
for(String key1:keySet1){
System.out.println("key1 = " + key1);
Map<String, List<String>> map2 = highlighting.get(key1);
System.out.println("map2 = " + map2);
Set<String> keySet2 = map2.keySet();
for(String key2:keySet2){
System.out.println("key2 = " + key2);
}
}
}
}
solr应用的更多相关文章
- solr服务中集成IKAnalyzer中文分词器、集成dataimportHandler插件
昨天已经在Tomcat容器中成功的部署了solr全文检索引擎系统的服务:今天来分享一下solr服务在海量数据的网站中是如何实现数据的检索. 在solr服务中集成IKAnalyzer中文分词器的步骤: ...
- Solr 排除查询
前言 solr排除查询也就是我们在数据库和程序中经常处理的不等于,solr的语法是在定语前加[-].. StringBuilder sbHtml=new StringBuilder(); shBhtm ...
- Solr高级查询Facet
一.什么是facet solr种以导航为目的的查询结果成为facet,在用户查询的结果上根据分类增加了count信息,然后用户根据count信息做进一步搜索. facet主要用于导航实现渐进式精确搜索 ...
- [Solr] (源) Solr与MongoDB集成,实时增量索引
一. 概述 大量的数据存储在MongoDB上,需要快速搜索出目标内容,于是搭建Solr服务. 另外一点,用Solr索引数据后,可以把数据用在不同的项目当中,直接向Solr服务发送请求,返回xml.js ...
- sorl6.0+jetty+mysql搭建solr服务
1.下载solr 官网:http://lucene.apache.org/solr/ 2.目录结构如下 3.启动solr(默认使用jetty部署) 在path路径下将 bin文件夹对应的目录加入,然后 ...
- Solr Facet 默认值
前言 今天在用Solr Facet遇到了默认值的问题,我用Facet.field查询发现数据总共100条,刚开始没有注意,发现少个别数据,但是用这几个个别的id查询又能查出来数据.才发现是Facet默 ...
- solr添加多个core
在D:\solr\solr_web\solrhome文件夹下: 1)创建core0文件夹 2)复制D:\solr\solr_web\solrhome\configsets\basic_configs/ ...
- solr定时更新索引遇到的问题(SolrDataImportProperties Error loading DataImportScheduler properties java.lang.NullPointerException)
问题描述 报如下错误,很显然,问题原因:空指针异常: ERROR (localhost-startStop-1) [ ] o.a.s.h.d.s.SolrDataImportProperties ...
- Solr实战:使用Hue+Solr实现标签查询
公司最近在研究多条件组合查询方案,Google的一位技术专家Sam和我们讨论了几个备选方案. Sam的信: 我做了进一步研究,目前有这么几种做法: 1) 最直接粗暴,只做一个主index,比如按行业+ ...
- solr.net的使用
引子 最近在做一个日志系统,用普通关系型数据库做数据查询遇到了查询的瓶颈,想到了用成熟的搜索应用服务,我所知道的比较成熟的搜索应用服务有solr和es(elasticsearch),由于时间比较仓促, ...
随机推荐
- 【容斥原理,莫比乌斯反演】用容斥替代莫比乌斯反演第二种形式解决gcd统计问题
名字虽然很长.但是其实很简单,对于这一类问题基本上就是看你能不能把统计的公式搞出来(这时候需要一个会推公式的队友) 来源于某次cf的一道题,盼望上紫的我让潘学姐帮我代打一道题,她看了看跟我说了题解,用 ...
- 洛谷 P3312 [SDOI2014]数表 解题报告
P3312 [SDOI2014]数表 题目描述 有一张\(N*M\)的数表,其第\(i\)行第\(j\)列(\(1\le i \le n\),\(1 \le j \le m\))的数值为能同时整除\( ...
- codeforces 217E 【Alien DNA】
倒序考虑每一个操作,对于一个操作$[l, r]$,他产生的影响区间将是$[r+1,r + r + l - 1]$,如果$r+l-1>K$的话,$K$之后的区间我们是不关心的. 暴力扫描这个区间 ...
- java如何优雅的实现时间控制
前言:最近小王同学又遇到了一个需求:线上的业务运行了一段时间,后来随着使用人数增多,出现了一个问题是这样的,一个订单会重复创建几次,导致数据库里出现了很多垃圾数据.在测试同学的不断测试下,发现问题出在 ...
- PID控制算法的C语言实现六 抗积分饱和的PID控制算法C语言实现
所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制 ...
- WIFI Direct(Wi-Fi P2P)
Wi-Fi Direct技术是Wi-Fi产业链向蓝牙技术发起的挑战,它试图完全取代蓝牙 Wi-Fi Direct是一种点对点连接技术,它可以在两台station之间直接建立tcp/ip链接,并不需要A ...
- Tensorflow在CIFAR-10构建CNN
使用Tensorflow在CIFAR-10二进制数据集上构建CNN 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 Tensorflow机器学习实战指南 利用Tensorflow读取 ...
- 高可用rabbitmq集群服务部署步骤
消息队列是非常基础的关键服务,为保证公司队列服务的高可用及负载均衡,现通过如下方式实现: RabbitMQ Cluster + Queue HA + Haproxy + Keepalived 3台ra ...
- bzoj 1455: 罗马游戏
1455: 罗马游戏 Time Limit: 5 Sec Memory Limit: 64 MB Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最 ...
- linux命令df中df -h和df -i的区别
df 命令: linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息. 1.命令格式: df [选项] [ ...