1.什么是 Solr?
1.1.Lucene['lu:si:n]
![](https://i-blog.csdnimg.cn/blog_migrate/d88ecc675c83475061d8e19b3825177c.png)
介绍 Solr
之前,就不得不提业界大名鼎鼎的
Lucene
。
使用
Lucene
的方式主要有二种:一是自己编写程序,调用类库(创建索引、修改、删除、查询等);二是使用第三方基于 Lucene 编写的程序,如 Solr 等。
1.2.Solr['səulə]
![](https://i-blog.csdnimg.cn/blog_migrate/9f1c0e324507303e52cd08b070e9c16c.png)
Solr 是基于 Lucene 的企业级搜索引擎,是对 Lucene 的封装和扩展,是一个 war 包, 需要基于 Tomcat 等 web 容器运行。Solr 使项目更容易集成和开发搜索功能。
以下是 Solr 的官方简介:
Solr 是一个基于 Lucene 的 Java 搜索引擎服务器。Solr 提供了层面搜索、命中醒目 显示并且支持多种输出格式(包括 XML/XSLT 和 JSON 格式)。它易于安装和配置, 而且附带了一个基于 HTTP 的管理界面。
Solr 已经在众多大型的网站中使用,较为成熟 和稳定。Solr 包装并扩展了 Lucene,所以 Solr 的基本上沿用了 Lucene 的相关术语。更重要的是,Solr 创建的索引与 Lucene 搜索引擎库完全兼容。通过对 Solr 进行适当的配置, 某些情况下可能需要进行编码,Solr 可以阅读和使用构建到其他 Lucene 应用程序中的 索引。此外,很多 Lucene 工具(如 Nutch、 Luke)也可以使用 Solr 创建的索引。
总之:solr 是一个 java 搜索引擎服务器(是一套 war 程序),内部集成了 Lucene(apache 提供的一些对搜索引擎做支持的 jar 包)。 Solr 的替代产品有 ElasticSearch(ES)。.
![](https://i-blog.csdnimg.cn/blog_migrate/9e71d96b2619be8ce586d747b33f7434.png)
2.为什么使用 Solr?
关系型数据库 RDBMS
虽然功能强大,但是不擅长文本数据的全文搜索。表现在两
方面:
1. 只能用
Like
模糊查询,性能非常低
2. 不支持(语义)分词技术(PostgreSQL 数据库除外)
而搜索引擎则不同,是专门擅长文本内容搜索的。Lucene
虽然功能强大,但只是 一个基础工具包,要想在一个项目中基于 Lucene
开发搜索功能,过于复杂、代码量大。 采用封装了 Lucene
的
Solr
引擎则方便很多。
Solr
具有如下优势:
(1)solr 是将整个索引操作功能封装好了的搜索引擎系统
(
企业级搜索引擎产品
)
(2)solr 可以部署到单独的服务器上
(WEB
服务
)
,它可以提供服务,我们的业务系统就只要发送请求,接收响应即可,降低了业务系统的负载
(3)solr 部署在专门的服务器上,它的索引库就不会受业务系统服务器存储空间的限制
(4)solr 支持分布式集群,索引服务的容量和能力可以线性扩展
3.Solr 工作原理和概念
Solr 做的事很简单,帮你找想要的信息。提供信息的过程称之为
Indexing
(索引)由 Indexer
(索引器)完成,找信息的过程称之为
Query
(检索)。
Solr 对外提供标准的
http
接口来实现对数据的索引的增加、删除、修改、查询。在 Solr
中,用户通过向部署在
servlet
容器中的
Solr Web
应用程序发送
HTTP
请求来启动索引和搜索。
Solr 接受请求,确定要使用的适当
SolrRequestHandler
,然后处理请求。通过 HTTP 以同样的方式返回响应。默认配置返回 Solr
的标准
XML
响应,也可以配置
Solr
的备用响应格式。
3.1.原理
![](https://i-blog.csdnimg.cn/blog_migrate/50c1a75feeb0d63abb37c9a62aa7c847.png)
1 .创建索引
从原始文件中提取一些可以用来搜索的数据(封装成各种 Field
),把各
Field
再封装Document
,然后对
Document
进行分析(对各字段分词),得到一些索引目录写入索引库,Document
本身也会被写入一个文档信息库;
2.根据索引查询
根据关键词解析(Query Parser
)出查询条件
Query(Termquery)
,利用索引搜索
器(IndexSearcher)去索引库获取文档
id
,然后再根据文档
id
去文档信息库获取文档
信息
3.2.举个栗子
你有一本菜谱,每次你学会一道菜的时候,将详细步骤记录在菜谱中,并记录 一个页码和一些关键信息。经过努力,已经学会了很多菜肴。某一天,你要做一道 菜,但是记不清步骤了,需要翻菜谱,通过关键信息和页码,你快速找到了烹饪方法,比起一页页去翻菜谱,你快了很多倍Solr 允许你建立各种各样的索引,上面这个例子中,你索引了菜肴的关键信息, 有时候,还可以索引一些其他信息,比如制作菜肴的难度,需要花费的时间等。 你可以通过 Schema
来控制
solr
要索引哪些信息。
3.3.Solr 的世界观
Solr 对信息处理的基本单位是文档(Document),RDBMS 中的每一数据 在 Solr 中是一个文档。 对于菜谱数据的 Document,包含了佐料、步骤、时间、难度等要素对于人这个 Document 来说,可以包含姓名、年龄、爱好等要素。 Solr 把这些组成要素看做是 Fields(字段),姓名可以看做是一个 Field, 姓和名又可以看做是 Fields.Fields 可以包含不同类型的数据,对于书籍的名字可以认为是一个 text(文本/字符串),书籍的售价可以是一个number(数值/浮点型)。一旦你 指定了 Field 的数据类型,Solr 就可以以你想要的那种形式使用。
3.4.Solr 索引操作
可以向 Solr 索引 servlet 传递 4 个不同的索引请求:
(1) add/update 允许向 Solr 添加文档或更新文档。直到提交后才能搜索到这些添 加和更新。
(2) commit 告诉 Solr,应该使上次提交以来所做的所有更改都可以搜索到。
(3) optimize 重构 Lucene 的文件以改进搜索性能。索引完成后执行一下优化通常比较好。如果更新比较频繁,则应该在使用率较低的时候安排优化。一个索引无需优化也可以正常地运行。优化是一个耗时较多的过程。
(4) delete 可以通过 id 或查询来指定。按 id 删除将删除具有指定 id 的文档;按查询删除将删除查询返回的所有文档。
4.如何使用 Solr?
参考《Solr 技术分析及运用.pdf
》的
1.2
节开始内容
4.1.下载 Solr
选择 4.9.1 这个稳定版本
![](https://i-blog.csdnimg.cn/blog_migrate/55be7e854e017a2c84b4836269c94b23.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5b938048bc410fd911e4a4c400284647.png)
4.2.安装 Solr 服务
由于 Solr
本身就是一个
war
包,因此安装就等于是部署到
Tomcat
。解压下载的
zip包,将 dist\solr-4.9.1.war
文件复制到
tomcat
的
webapps
目录下,并将文件命名为
solr.war
![](https://i-blog.csdnimg.cn/blog_migrate/44de418a003d4be83f8485f393fd0d57.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9a16f8ba271ce255b550bb4f091871ef.png)
![](https://i-blog.csdnimg.cn/blog_migrate/432cfa3e0b73ca77a2e564e064544d9e.png)
把 zip 包解压后的 example\lib\ext 下所有的 jar 包,复制到 tomcat 的 lib 目录下
![](https://i-blog.csdnimg.cn/blog_migrate/13ca94eb7c524dd499d655deac8f39ee.png)
在计算机本地新建一个文件夹 D:\__dev-tools\solr-4.9.1(当然你可以随便起名字,下面简称 SOLR_HOME), 然后把 zip 解压后的
solr-4.9.1\example\solr 下的所有文件复制到 SOLR_HOME 下:
![](https://i-blog.csdnimg.cn/blog_migrate/f6e730b5963b61053b4e13db2b2f60b7.png)
启动 Tomcat,待启动成功后,关闭 Tomcat。注意,此时 solr.war 包已经被 解压成 solr 文件夹。打开 Tomcat 的 webapps 目录,删除 solr.war 包,保留 solr文件夹。
![](https://i-blog.csdnimg.cn/blog_migrate/3ce6d72e043397b44ea537f89d2a597b.png)
修改配置文件 Tomcat 下 webapps\solr\WEB-INF\web.xml,让 Tomcat 中的 Solr 引用 solr/home 变量对应的路径 SOLR_HOME:
![](https://i-blog.csdnimg.cn/blog_migrate/673a977e665bea7326ac2f24707a4e6d.png)
关于 D:\__dev-tools\apache-tomcat-7.0.61\webapps\solr
和
SOLR_HOME
的关系,你可以认为 Tomcat
下的
solr
是一个搜索引擎服务,而
SOLR_HOME
则是一个实例(类似Oracle 的服务器和实例概念)。具体某个项目的数据搜索,要在
SOLR_HOME
这个实例中去配置。
启动 Tomcat
,用浏览器访问
http://localhost:
端口号
/solr/
,如出现以下界面则
Solr
部署成功
:
5.中文分词器
5.1.为什么要用分词器?
为了实现更准确的语义结果。世界上很多语言,在进行文本查找时都需要解决分词的问题,中文也如此。比如,给定一串字符串“中华人民共和国”,搜索引擎需要知道,这个字符串可以拆分成“中华”、“人民”、“共和国”、“中华人民”、“华人”等多个词,但是不能拆分为“华人民”、“民共和”等词;同样的,当你在百度以“天真”作为关键字进行搜索,你一般是希望找到“天真无邪”、“xxx 非常天真可爱”等结果,而不是“今天真热”的结果。分词器就是为了解决这类问题,让搜索引擎的结果准确度大大提高。
5.2.下载分词器
常见的 JAVA
分词器
: word 分词器、 Ansj 分词器、 Stanford 分词器、 IKAnalyzer 分词器
本课程选用的是
IKAnalyzer
分词器solr 如果是
3.x
版本的用
IKAnalyzer2012_u6.zip如果是 4.x
版本的用
IK Analyzer2012FF_hf1.zip
,一定要对应上,要不然会配置失败。
下载地址:
https://code.google.com/archive/p/ik-analyzer/downloads
,如果无法下载,就用附件 IK Analyzer 2012FF_hf1.zip
压缩包。
5.3.配置分词器
把下载的
IK Analyzer2012FF_hf1.zip
解压,把如下这个
jar
复制到
Tomcat
的webapps\solr\WEB-INF\lib 目录下
把 IKAnalyzer.cfg.xml
和
stopword.dic
文件拷贝到
Tomcat
的
webapps\solr\WEB-INF\classes
目录下
SOLR_HOME
\itrip\conf\schema.xml
增加一个名为
text_ik
的字段类型,该字段类型表示文本类型的由 IKAnalyzer 分词器进行分词处理
:
<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>
修改
SOLR_HOME
\itrip\conf\schema.xml
将
hotelName
和
address
指定成为
text_ik
类型,
则对于
Solr
来说,这两个字段不再简单作为字符串处理,而是交给分词器处理:
<field name="hotelName" type="text_ik" indexed="true" stored="true"/>
<field name="address" type="text_ik" indexed="true" stored="true"/>
重启 Tomcat
,测试分词器是否成功
5.4.Solr 查询语法
q
– 查询字符串。
’*:*’
表示任何字段任何条件(无条件查所有)
,
‘address:
北京
’
表示查 address
字段包含
北京
的数据
fl
– 指定返回那些字段内容,用逗号或空格分隔多个。
start
– 返回第一条记录在完整找到结果中的偏移位置,
0
开始,一般分页用。
rows
– 指定返回结果最多有多少条记录,配合
start
来实现分页。
sort
– 排序,格式:
sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]
示例:
(inStock desc, price asc)表示先 “inStock” 降序,
再 “
price
” 升序,默认是相关性降序。
wt
–
(writer type)
指定输出格式,可以有
xml, json, php, phps,
后面
solr 1.3
增加的,要用通知我们,因为默认没有打开。
fq
– (filter query)过虑查询,作用:在
q
查询符合结果中同时是
fq
查询符合的,
例如:q=mm&fq=date_time:[20081001 TO 20091031]
,找关键字
mm
,并且date_time 是
20081001
到
20091031
之间的。
5.5.Solr 多字段匹配
针对酒店数据,如果 hotelName、
address
众多字段一个个写在搜索条件中,很冗
长,那么改进的办法就是多字段匹配——一个关键字可匹配多个字段去搜索。
需要修改
SOLR_HOME
\itrip\conf\schema.xml
,作用是按查询条件中的
kw
的值,分
别去
hotelName
和
address
字段进行搜索。比如搜索
’kw:
北京
’
会搜索出所有酒店名和
地址中包含北京二字的数据。
<field name="kw" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<copyField source="hotelName" dest="kw"/>
<copyField source="details" dest="kw"/>
<copyField source="address" dest="kw"/>复制域(复制字段)
注意,增加此配置后需要重启
Solr
所在的
Tomcat
,并重新执行数据导入(需要重建索
引)。
5.6. solrj
如何把
solr
项目集成到
java
项目中来。solr 本身提供了对外调用的
Http
接口,利用
Http请求可以直接从 solr
中获取数据。为了方便
Java
程序员调用
solr
,
Apache
提供了基于
solr操作的 solrj
程序包。
5.6.1.添加依赖
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>5.3.1</version>
</dependency>
5.6.2.封装 Solr 查询对象
在程序中创建
solr
查询的接收对象(省略
get
、
set
)
5.6.3.java 调用 Solr
编写如下 java 代码调用 Solr 进行搜索:
![](https://i-blog.csdnimg.cn/blog_migrate/c448bb60839dd6def7eefdae08917b43.png)
❤如果文章对您有所帮助,就请在文章末尾的左下角把大拇指点亮吧!(#^.^#);
❤如果喜欢HuangJunqi~先生分享的文章,就请给点个关注吧!(๑′ᴗ‵๑)づ╭❤~;
❤对文章有任何问题欢迎小伙伴们下方留言