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. DATA 转 16 进制

    // 转 16进制 编码 NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMo ...

  2. [python]PyCharm安装与激活

    一.安装 1.去官网下载安装包(http://www.jetbrains.com/pycharm/download/#section=windows) 2.下载完成之后双击即可点击安装,按照自己需求选 ...

  3. Java:泛型擦除

    https://docs.oracle.com/javase/tutorial/java/generics/erasure.html

  4. springBoot 自定义redisTemplate

    package com.atirm.mybatismutiplesource.config.RedisConfig; import com.atirm.mybatismutiplesource.ent ...

  5. 使用 adb 命令一次性为多个设备安装 apk

    使用 adb 命令一次性为多个设备安装 apk 原创 2016年07月15日 10:40:53 3154 命令简介 adb install [-lrtsdg] (file) 把包文件推送到设备上并安装 ...

  6. lintcode671 循环单词

    循环单词   The words are same rotate words if rotate the word to the right by loop, and get another. Cou ...

  7. java length属性、length()、size()

    length属性 length是属性,用于说明数组的长度. String []list={"wo","shi","shuaibi"}; Sy ...

  8. [Install] TeamViewer

    安装TeamViwer 1. $ sudo apt-get -f install 2. 使用gdebi安装TeamViwer. 所以先安装gdebi package. $ sudo apt-get i ...

  9. metamask注记词

    leaf orbit poet zebra toy day put dinosaur review cool pluck throw(m) 一个钱包地址 里面有多个账号 菲苾代表了不同网络

  10. 从wait_type入手模拟SQL Server Lock

    一.LCK_M_S,等待获取共享锁 开始一SQL TRAN,其中执行对某数据的UPDATE.但并不COMMIT,也不ROLLBACK. begin tran update [dbo].[HR_Empl ...