Solr 简 介

采用Java开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http G Solret操作提出查找请求,并得到XML格式的返回结果。

Solr 与 Lucene 的关系

Lucene是一套信息检索工具包,但并不包含搜索引擎系统,它包含了索引结构、读写索引工具、相关性工具、排序等功能,因此在使用Lucene时你仍需要关注搜索引擎系统,例如数据获取、解析、分词等方面的东西。

首先Solr是基于Lucene做的 , Solr的目标是打造一款企业级的搜索引擎系统,因此它更接近于我们认识到的搜索引擎系统,它是一个搜索引擎服务,通过各种API可以让你的应用使用搜索 服务,而不需要将搜索逻辑耦合在应用中。而且Solr可以根据配置文件定义数据解析的方式,更像是一个搜索框架,它也支持主从、热换库等操作。还添加了高亮、facet等搜索引擎常见功能的支持

Solr 的搭建运行

1、解压solr-4.6.0.zip到你想到存放的路径,比如:e:/solr

2、cmd打开命令行窗口,进入E:/solr/example目录

3、执行命令:java -jar start.jar

4、通过第三步以后,系统会启动solr自带的jetty服务器,通过 http://localhost:8983/solr/便可访问solr。

此时,solr已成功启动

solrj 的使用

package cn.itcast.dao;

import java.io.IOException;
import java.util.List;
import java.util.Map; import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
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.apache.solr.common.params.SolrParams;
import org.junit.Test; import cn.itcast.bean.Product; /**
* 使用solrJ 向solr 提交请求,增删改查,
* solrJ 底层页是发送http 协议...
* @author Administrator
*
*/
public class SolrJDao { public void addIndex(Product product) throws SolrServerException, IOException
{
//第一步,我需要跟solr 服务器建立起一个连接..
String urlString = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(urlString); // //在solr 当中有一些默认的字段,这个字段在配置文件里面...
// SolrInputDocument doc=new SolrInputDocument();
// schema.xml 用来定义索引的结构,用来定义document 结构...
solr.addBean(product);
solr.commit();
} @Test
public void adddynamicField() throws SolrServerException, IOException
{
//第一步,我需要跟solr 服务器建立起一个连接..
String urlString = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(urlString); //在solr 当中有一些默认的字段,这个字段在配置文件里面...
SolrInputDocument doc=new SolrInputDocument();
doc.addField("id", "ccccccc"); doc.addField("name", "8888888");
// schema.xml 用来定义索引的结构,用来定义document 结构...
doc.addField("desc_s", "wwwww");
doc.addField("price", 1f);
solr.add(doc);
solr.commit();
} public void updateIndex() throws IOException, SolrServerException{
//第一步,我需要跟solr 服务器建立起一个连接..
String urlString = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(urlString);
Product product=new Product();
product.setId(2);
product.setName("毛衣的毛衣黑色毛衣");
product.setDesc("横挑眉毛竖挑眼,完全没缺点..");
product.setPrice(9f);
solr.addBean(product);
solr.commit(); } public void delIndex(String id) throws SolrServerException, IOException{
String urlString = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(urlString);
solr.deleteById(id);
solr.commit();
} public void findIndex() throws SolrServerException{
String urlString = "http://localhost:8983/solr";
SolrServer solr = new HttpSolrServer(urlString);
//查询条件...
SolrQuery solrParams=new SolrQuery();
solrParams.setStart(0);
solrParams.setRows(10); //name:苹果 根据description:苹果
solrParams.setQuery("name:苹果");
// solrParams.setQuery("description:苹果");
//首先,我需要开启高亮...
solrParams.setHighlight(true);
solrParams.setHighlightSimplePre("<font color='red'>");
solrParams.setHighlightSimplePost("</font>"); //我需要那些字段进行高亮显示..
solrParams.setParam("hl.fl", "name,description"); //返回结果集,结果包含没有高亮的结果,高亮的结果..
QueryResponse queryResponse=solr.query(solrParams);
SolrDocumentList solrDocumentList=queryResponse.getResults();
//返回高亮过后的结果...
/**
* 假设我要迭代这样的一个map
* 我必须两个map 对应的这个key 代表的是撒..
*
* 1:第一个map 代表的每条记录的id
* 2:第二个map 的可以 代表的我要高亮的字段..
*
*
*/
Map<String,Map<String, List<String>>> listMap=queryResponse.getHighlighting(); for(SolrDocument solrdocument:solrDocumentList){
System.out.println("==="+solrdocument.toString());
Map<String, List<String>> fieldsMap=listMap.get(solrdocument.get("id"));
List<String> highname=fieldsMap.get("name");
List<String> highdesc=fieldsMap.get("description");
System.out.println("highname======"+highname);
System.out.println("highdesc====="+highdesc);
}
} }
package cn.itcast.bean;

import org.apache.solr.client.solrj.beans.Field;

public class Product {

    @Field(value="id")
private int id; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getDesc() {
return desc;
} public void setDesc(String desc) {
this.desc = desc;
} public float getPrice() {
return price;
} public void setPrice(float price) {
this.price = price;
}
@Field(value="name")
private String name;
@Field(value="description")
private String desc;
@Field(value="price")
private float price; }
package cn.itcast.junit;

import java.io.IOException;

import org.apache.solr.client.solrj.SolrServerException;
import org.junit.Test; import cn.itcast.bean.Product;
import cn.itcast.dao.SolrJDao; public class JunitTest {
private SolrJDao solrJDao=new SolrJDao();
@Test
public void testAdd() throws SolrServerException, IOException{
for(int i=1;i<=2;i++){
Product product=new Product();
product.setId(i);
product.setName("苹果(Apple)iPhone 5c 16G版 3G手机(白色)电信版");
product.setDesc("选择“购机送费版”北京用户享全新4G合约套餐资费全网最低!");
product.setPrice(9f);
solrJDao.addIndex(product);
} }
@Test
public void testdel() throws SolrServerException, IOException{ solrJDao.delIndex("1");
}
@Test
public void testupdate() throws IOException, SolrServerException{
solrJDao.updateIndex();
}
@Test
public void testfind() throws SolrServerException{
solrJDao.findIndex();
} }

shema.xml 的介绍

schema.xml配置文件是用于定义index索引库的结构,有点类似于数据表表的定义。

当我们打开schema.xml配置文件时,也许会被里面密密麻麻的代码所吓倒,其实不必惊慌,里面其实就两个东西filed和fieldType。

1、field–类似于数据表的字段

<fields>
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" omitNorms="true" default="df"/>
.....//省略
<field name="_version_" type="long" indexed="true" stored="true"/><!--此字段为最好不要删除哦!非要删除,请把solrconfig.xml中的updateLog注释,但不建议这样-->
</fields>

属性介绍:
(1)、name:字段名称
(2)、type:字段类型(此处type不是java类型,而是下面定义的fieldType)
(3)、indexed:是否索引?true--solr会对这个字段进行索引,只有经过索引的字段才能被搜索、排序等;false--不索引
(4)、stored:是否存储?true--存储,当我们需要在页面显示此字段时,应设为true,否则false。
(5)、required:是否必须?true--此字段为必需,如果此字段的内容为空,会报异常;false--不是必需
(6)、multiValued:此字段是否可以保存多个值?
(7)、omitNorms:是否对此字段进行解析?有时候我们想通过某个字段的完全匹配来查询信息,那么设置 indexed="true"、omitNorms="true"。
(8)、default:设置默认值

2、fieldType–字段类型

<types>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
.....//省略
<fieldType name="text_general" positionIncrementGap="100">
<analyzer type="index">
<tokenizer/>
<filter ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter/>
</analyzer>
<analyzer type="query">
<tokenizer/>
<filter ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter/>
</analyzer>
</fieldType>
</types>

属性说明:
(1)、name:类型名称,<field>中的type引用的就是这个name
(2)、class:solr自定义的类型
(3)、<analyzer type="index">定义建立索引时使用的分词器及过滤器
(4)、<analyzer type="query">定义搜索时所使用的分词器及过滤器
(5)、 <tokenizer/>定义分词器
(6)、<filter/>定义过滤器

3、uniqueKey

<uniqueKey>id</uniqueKey>
类似于数据表数据的id,solr索引库中最好定义一个用于标示document唯一性的字段,此字段主要用于删除document。

4、<copyField/>

<copyField source=”cat” dest=”text”/>
实际项目中为了方便查询,我们会把多个需要查询的字段合并到一个字段里,方便查询。

举例:

产品搜索,关键词不应该只匹配产品标题,还应该匹配产品关键词及产品简介等,那么在建立索引库时,可以把标题、产品关键词、简介放到一个叫text的字段中,搜索时直接搜text字段。

<fields>
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="title" type="text_general" indexed="true" stored="true"/>
<field name="keywords" type="text_general" indexed="true" stored="true" omitNorms="true"/>
<field name="description" type="string" indexed="true" stored="true" multiValued="true"/>
</fields>

<copyField source="title" dest="text"/>
<copyField source="keywords" dest="text"/>
<copyField source="description" dest="text"/>

5、

动态的字段,使用java代码增加索引时可以动态的增加索引的name值,例如desc_i,具体使用在上面代码中adddynamicField()方法已有体现

solrconfig介绍

对于solr4.x的每个core有两个很重要的配置文件:solrconfig.xml和schema.xml,下面我们来了解solrconfig.xml配置文件。

具体很详细的内容请细读solrcofig.xml配置文件中的英文说明。

1、

“solr.”--代表solr home,即core所在的目录,如:/example/solr/collection1

2、

<luceneMatchVersion>LUCENE_42</luceneMatchVersion>

告诉solr底层使用的是lucene4.2

3、

<lib dir="../../../contrib/extraction/lib" regex=".*.jar" />

solr引用的jar包,以“solr.”为基准,当dir对应的目录不存在时,solr会忽略此<lib>

4、

<dataDir>${solr.data.dir:}</dataDir>

配置data目录的存放位置,data目录中存放了index和log文件。默认为solr home下面的data文件夹

5、

<lockType>${solr.lock.type:native}</lockType>
设置索引库的锁方式,主要有三种:
(1)、single:适用于只读的索引库,即索引库是定死的,不会再更改
(2)、native:使用本地操作系统的文件锁方式,不能用于多个solr服务共用同一个索引库。Solr3.6 及后期版本使用的默认锁机制。
(3)、simple:使用简单的文件锁机制

6、更新处理器

<updateLog>
<str name="dir">${solr.ulog.dir:}</str>
</updateLog>
设置索引库更新日志,默认路径为solr home下面的data/tlog。随着索引库的频繁更新,tlog文件会越来越大,所以建议提交索引时采用硬提交方式<autoCommit>,即批量提交。

<autoCommit>
<maxTime>15000</maxTime>
<maxDocs>10000</maxDocs>
<openSearcher>false</openSearcher>
</autoCommit>
自动硬提交方式:
maxTime:设置多长时间提交一次
maxDocs:设置达到多少文档提交一次
openSearcher:文档提交后是否开启新的searcher,如果false,文档只是提交到index索引库,搜索结果中搜不到此次提交的文档;如果true,既提交到index索引库,也能在搜索结果中搜到此次提交的内容。

7、

<maxBooleanClauses>1024</maxBooleanClauses>

设置boolean 查询中,最大条件数。在范围搜索或者前缀搜索时,会产生大量的 boolean 条件,如果条件数达到这个数值时,将抛出异常,限制这个条件数,可以防止条件过多查询等待时间过长。

8、solr查询缓存机制

为了提升查询效率,solr提供了很多方法。 缓存在 Solr 中充当了一个非常重要的角色,Solr 中主要有这三种缓存:

<filterCache class="solr.FastLRUCache" size="512" initialSize="512" autowarmCount="0"/>

<queryResultCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0"/>

<documentCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0"/>

<queryResultMaxDocsCached>200</queryResultMaxDocsCached>

<maxWarmingSearchers>2</maxWarmingSearchers>
Filter cache(过滤器缓存),用于保存过滤器(fq 参数)和层面搜索的结果
Document cache(文档缓存),用于保存 lucene 文档存储的字段
Query result(查询缓存),用于保存查询的结果

还有第四种缓存,lucene 内部的缓存,不过该缓存外部无法控制到。
通过这 3 种缓存,可以对 solr 的搜索实例进行调优。调整这些缓存,需要根据索引库中文档的数量,每次查询结果的条数等。
在调整参数前,需要事先得到 solr 示例中的以下信息:

索引中文档的数量
每秒钟搜索的次数
过滤器的数量
一次查询返回最大的文档数量
不同查询和不同排序的个数

这些数量可以在 solr admin 页面的日志模块找到。假设以上的值分别为:

索引中文档的数量:1000000
每秒钟搜索的次数:100
过滤器的数量:200
一次查询返回最大的文档数量:100
不同查询和不同排序的个数:500

然后可以开始修改 solrconfig.xml 中缓存的配置了,第一个是过滤器缓存:
1

<filterCache class="solr.FastLRUCache" size="200" initialSize="200" autowarmCount="100"/>

第二个是查询结果缓存:
1

<queryResultCache class="solr.FastLRUCache" size="500" initialSize="500" autowarmCount="250"/>

第三个是文档缓存:
1

<documentCache class="solr.FastLRUCache" size="11000" initialSize="11000" />

这几个配置是基于以上的几个假设的值进行调优的

9、solr请求处理器

为了提供了类似webservice的功能,可以通过http请求solr搜索。

<requestHandler name="/select" class="solr.SearchHandler">
<!-- 设置默认的参数,但这些参数的值可以被请求地址中的参数所替代-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int><!--显示数量-->
<str name="wt">json</str><!--显示格式-->
<str name="df">text</str><!--默认搜索字段-->
</lst>
</requestHandler>

了解Solr的更多相关文章

  1. solr服务中集成IKAnalyzer中文分词器、集成dataimportHandler插件

    昨天已经在Tomcat容器中成功的部署了solr全文检索引擎系统的服务:今天来分享一下solr服务在海量数据的网站中是如何实现数据的检索. 在solr服务中集成IKAnalyzer中文分词器的步骤: ...

  2. Solr 排除查询

    前言 solr排除查询也就是我们在数据库和程序中经常处理的不等于,solr的语法是在定语前加[-].. StringBuilder sbHtml=new StringBuilder(); shBhtm ...

  3. Solr高级查询Facet

    一.什么是facet solr种以导航为目的的查询结果成为facet,在用户查询的结果上根据分类增加了count信息,然后用户根据count信息做进一步搜索. facet主要用于导航实现渐进式精确搜索 ...

  4. [Solr] (源) Solr与MongoDB集成,实时增量索引

    一. 概述 大量的数据存储在MongoDB上,需要快速搜索出目标内容,于是搭建Solr服务. 另外一点,用Solr索引数据后,可以把数据用在不同的项目当中,直接向Solr服务发送请求,返回xml.js ...

  5. sorl6.0+jetty+mysql搭建solr服务

    1.下载solr 官网:http://lucene.apache.org/solr/ 2.目录结构如下 3.启动solr(默认使用jetty部署) 在path路径下将 bin文件夹对应的目录加入,然后 ...

  6. Solr Facet 默认值

    前言 今天在用Solr Facet遇到了默认值的问题,我用Facet.field查询发现数据总共100条,刚开始没有注意,发现少个别数据,但是用这几个个别的id查询又能查出来数据.才发现是Facet默 ...

  7. solr添加多个core

    在D:\solr\solr_web\solrhome文件夹下: 1)创建core0文件夹 2)复制D:\solr\solr_web\solrhome\configsets\basic_configs/ ...

  8. solr定时更新索引遇到的问题(SolrDataImportProperties Error loading DataImportScheduler properties java.lang.NullPointerException)

    问题描述 报如下错误,很显然,问题原因:空指针异常: ERROR (localhost-startStop-1) [   ] o.a.s.h.d.s.SolrDataImportProperties ...

  9. Solr实战:使用Hue+Solr实现标签查询

    公司最近在研究多条件组合查询方案,Google的一位技术专家Sam和我们讨论了几个备选方案. Sam的信: 我做了进一步研究,目前有这么几种做法: 1) 最直接粗暴,只做一个主index,比如按行业+ ...

  10. solr.net的使用

    引子 最近在做一个日志系统,用普通关系型数据库做数据查询遇到了查询的瓶颈,想到了用成熟的搜索应用服务,我所知道的比较成熟的搜索应用服务有solr和es(elasticsearch),由于时间比较仓促, ...

随机推荐

  1. HDOJ:1533-Going Home(最小费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 解题心得: 第一次写最小费用流的题,去hdoj上找了一个入门级题目,建图比较简单,用了spfa和 ...

  2. WebRTC中Android Demo中的摄像头从采集到预览流程

    APPRTC-Demo调用流程 1.CallActivity#onCreate 执行startCall开始连接或创建房间 2.WebSocketClient#connectToRoom 请求一次服务器 ...

  3. BZOJ4247_挂饰_KEY

    题目传送门 背包的变形,不得不说卡了我很久(估计是下午睡傻了). 设f[i][j]为前i个物品剩下j个挂钩. f[i][j]=max(f[i-1][j],f[i-1][max(j-a[i].x,0)+ ...

  4. ORB-SLAM(八)ORBmatcher 特征匹配

    该类负责特征点与特征点之间,地图点与特征点之间通过投影关系.词袋模型或者Sim3位姿匹配.用来辅助完成单目初始化,三角化恢复新的地图点,tracking,relocalization以及loop cl ...

  5. 解决replace格式替换后光标定位问题

    场景:格式化银行卡444格式 手机号344格式 身份证号684格式 校验数据格式,replace后光标定位错乱 或光标一直定位在最后 解决,只针对input,代码用的vue: 获取光标位置: getC ...

  6. VIN码识别:让VIN码采集so easy!

    近几年汽车后市场呈喷井式发展,在过去的半年,汽车后市场规模已高达万亿级,产业前景广阔,与此同时行业运营也受信息区域化.数据不统一的制约,让企业面临着效率低下.规模化运行困难的痛点. 在汽车配件市场中, ...

  7. OSG-阴影

    本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...

  8. Python零基础入门必知

    Python自学知识点总结 //2018.10.09 1. Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido ...

  9. 微信小程序之基础案例详细解释

    这是案例的初始页面 首先关于这个案例上面的app.json做一个特别详细的解释 首先提醒一下.json文件不能有注释,因此如果要复制的话,请把注释删去 //关于app.json详细学习 { //pag ...

  10. 157. Unique Characters 【LintCode by java】

    Description Implement an algorithm to determine if a string has all unique characters. Example Given ...