老牌全文搜索引擎 Solr

感情迁移 提交于 2019-11-27 15:19:49

介绍

Solr是一个Java开发的基于Lucene的 企业级 开源 全文搜索 平台。
它采用的是反向索引,即从关键字到文档的映射过程。
Solr的资源以Document为对象进行存储,每个文档由一系列的 Field 构成,每个Field 表示资源的一个属性。
文档的Field可以被索引, 以提工高性能的搜索效率。
一般情况下文档都包含一个能唯一表示该文档的id字段。


应用场景

如某房屋租赁站点的租房频道, 其房屋搜索功能可通过Solr来实现,每条租房信息就是solr中的一篇文档。
solr可以基于编译好的全文索引, 提供高性能的标签筛选租房信息,甚至是自定义关键字的高效搜索,查询结果的统计效率也极好。


全文搜索引擎比较

1. Sphinx  相较于solr,与数据库整合较好,操作更简单,性能更好。 但是需要商业授权。
2. Lucene  底层的索引程序 Java类库。
3. Solr  基于lucene,相较于Sphinx,更成熟完善,实时索引,扩展性好,支持特性多,对中文分词支持更好。在稳定的前提下, 业界用Solr的最多。
4. Elasticsearch  基于lucene,较之于solr有更好的分布式支持。


Solr优点

1. 相较于Mysql有更好的文本搜索性能
2. 高效、灵活的缓存功能
3. 高亮显示搜索结果
4. 基于Solr的查询彻底杜绝了在Mysql中存在的sql注入安全问题
5. 基于Solr的facet特性提供标签聚合统计功能,实现商品在不同筛选标签下的计数统计,进而能人性化的将产品数目为0的筛选标签灰化,同样的功能在mysql中则难以实现
6. 提供基于Web的管理界面


安装

#新版本的solr 5.x不依赖于tomcat,可独立运行服务,只需安装java环境

#安装jdk
sudo yum install java-1.7.0-openjdk

#官网下载solr发行版
wget http://www.us.apache.org/dist/lucene/solr/5.3.1/solr-5.3.1.tgz
tar -zxvf solr-5.3.1.tgz

#配置环境变量
sudo vim /etc/profile
#追加一行
export PATH=PATH:solr安装目录/bin
#加载配置文件
. /etc/profile
#测试solr是否能正常运行
solr status  #回显No Solr nodes are running.说明solr安装成功

#如果从便于管理的角度, 可以把solr注册为service
solr安装目录/bin/install_solr_service.sh


服务管理

## 启动solr服务,运行一个solr实例
solr start  #启动solr为独立模式 standalone (core) 
或者
solr start -cloud  #启动solr为云模式 SolrCloud mode (collection)

## solr服务状态
solr status

## solr服务启动后,我们可以在当前solr实例下创建core
## 以后的文档索引处理都将基于一个core来进行
solr create -c corename  #独立模式将创建core,云模式将创建collection



## solr自带了几个参考实例(每个实例预置了若干core),可以通过如下方式运行实例
solr -e exampleName
#exampleName包括
cloud        : SolrCloud example
dih          : Data Import Handler (rdbms, mail, rss, tika)
schemaless   : Schema-less example (schema is inferred from data during indexing)
techproducts : Kitchen sink example providing comprehensive examples of Solr features



数据处理


数据导入

    数据导入前需要配置schema和solrconfig, 然后可以按稍后的任意方法推送数据到solr中

############################################ Schema配置 ###############################################
Schema的意义类似于关系数据库中的表结构,它描述了solr中文档的字段结构、字段类型等
其中主要包含field, uniqueKey, fieldType的定义
我们在 server/solr/bbs/conf 目录下,创建schema.xml,来描述Schema


定义field(描述solr文档中每个字段的特性):
<field name="" type=""  indexed="true" stored="true" required="true" />
属性:
    name     字段名称(必选字段)
    type     字段类型(必选字段), 可选类型定义在当前schema.xml的一系列fieldType节点中
    indexed  该字段是否要被索引,从而字段可进行搜索和排序
    stored   该字段是否存储,还是仅建索引, true时查询结果可返回该字段值。如果该字段仅用于搜索不需要查询结果,建议设false提高性能    
    required 该字段是否必选
    default  该字段默认值
    multiValued    若字段包含多个值需要设为true    
    docValues      若字段有文档值则需要true,在faceting, grouping, sorting and function queries时有用,一般能加速索引的载入
    omitNorms      true时将忽略字段规范,可解除字段长度一致性限制,提升该字段的索引时间,节省内存
    termVectors    是否存储该字段的词向量,如果字段做MoreLikeThis的相似性查询,则应设true来提升性能。高亮功能依赖此项
    termPositions  是否存储词向量的位置信息,这会增加存储成本。高亮功能依赖此项
    termOffsets    是否存储词向量的位偏移信息,这会增加存储成本。高亮功能依赖此项


定义uniqueKey(指定唯一标识文档的字段):
常见为: <uniqueKey>id</uniqueKey>


定义fieldType:    
描述了solr文档字段的可用类型, 一般有:string, boolean, int, float, long, date ...
例如: <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
fieldType除了传统类型,亦可定义中文分词器引入的字段类型


############################################ solrconfig配置 ###############################################
solrconfig是solr的配置文件,它描述了solr的索引存储路径,请求处理器(/query、/export等)及缓存策略等
文件位于: server/solr/corename/conf/solrconfig.xml:

    

    这里介绍两类常用的导入数据方法,其他方法请参考官方手册

    方法1:Post命令接口 - 推送格式化文件数据到Solr中

post -c corename files|directories  #支持json、xml、csv、excel、word、pdf等等格式的文件

例如推送xml格式为例的一篇文档:
post -c corename exam.xml

## exam.xml
<add>
    <doc>
	<field name="id">SOLR1000</field>
	<field name="name">汤臣一品</field>
	<field name="city">上海</field>
	<field name="country">中国</field>
	<field name="desc">牛逼哄哄的高端住宅</field>
	<field name="date">2010-01-17T00:00:00.000Z</field>
    </doc>
</add>


    方法2:DIH(DataImportHandler)方法 - 导入其他数据源的数据到Solr中

    DIH包含多种导入类型:

        1.从DB导入

        2.从RSS导入

        3.从IMAP邮件服务导入

        4.从其他solr core拷贝

        5.通过Tika集成从其他格式文档如HTML, PDF, Doc导入

    更多细节可参考solr自带dih样例

    这里介绍DIH中的MysqlDB导入类型

安装java-mysql连接驱动:
sudo yum install mysql-connector-java
cp mysql-connector-java.jar server/solr-webapp/webapp/WEB_INF/lib/


拷贝 dist/solr-dataimporthandler-5.3.1.jar 到 server/solr-webapp/webapp/WEB_INF/lib/


修改solr配置文件 server/solr/corename/conf/solrconfig.xml:
添加:
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> 
    <lst name="defaults"> 
        <str name="config">data-config.xml</str> 
    </lst> 
</requestHandler>
还要添加:
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-\d.*\.jar"/> (在 regex="solr-cell-\d.*\.jar" 之前添加 )


创建data-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>  
	<dataSource type="JdbcDataSource"
				driver="com.mysql.jdbc.Driver"
				url="jdbc:mysql://localhost/django_blog"
				user="root"
				password=""/>  
	<document name="blog">  
		<entity name="blog_blog" pk="id"
				query="select id,title,content from blog_blog"
				deltaImportQuery="select id,title,content from blog_blog where ID='${dataimporter.delta.id}'" 
				deltaQuery="select id  from blog_blog where add_time > '${dataimporter.last_index_time}'"  
				deletedPkQuery="select id  from blog_blog where id=0">  
				<field column="id" name="id" />  
				<field column="title" name="title" />  
				<field column="content" name="content"/>  
		</entity>  
	</document> 
</dataConfig>

## data-config.xml说明:
query 用于初次导入到索引的sql语句。
      若数据表中的数据量非常大,不能一次索引完,则分批完成。查询语句query设置两个参数:${dataimporter.request.length} ${dataimporter.request.offset}
      query=”select id,title,content from blog_blog limit ${dataimporter.request.length} offset ${dataimporter.request.offset}”
      请求:http://localhost:8983/solr/collection2/dataimport?command=full-import&commit=true&clean=false&offset=0&length=10000
deltaImportQuery  根据ID取得需要进入的索引的单条数据。
deltaQuery        用于增量索引的sql语句,用于取得需要增量索引的ID。
deletedPkQuery    用于取出需要从索引中删除文档的的ID


#########################################################################


数据查询

基于http的get请求
可用参数:
q      #搜索关键字
fl     #指定返回字段
wt     #指定返回格式
index  #是否缩进
sort   #指定排序字段,默认按score倒序
hl     #指定高亮字段, 用法:hl=true&hl.fl=filedName

例子:
 ask &indent=true


#########################################################################


数据更新

Solr数据更新只需导入id相同的文档即可。
solr会根据文档的id字段唯一标识文档,如果导入的文档的id已经存在solr中,那么这份文档就被最新导入的同id的文档自动替换。


#########################################################################


数据删除

post -c corename "<delete><id>SOLR1000</id></delete>"  #删除指定id文档
post -c corename "<delete><query>city:上海</query></delete>"  #搜索删除查询匹配文档
post -c corename "<delete><query>city:上海 AND country:中国</query></delete>"  #搜索删除多个条件的查询匹配文档
post -c corename "<delete><query>*:*</query></delete>"  #清空solr文档



层面浏览 Facet

Facet特性提供了对某一字段下的标签进行聚合统计的功能



集成中文分词IK Analyzer





后台管理

服务启动后我们便能访问管理界面了,地址栏输入:
ip:8983 #ip为solr服务所在主机ip


管理界面 - Overview菜单

    截图如下:

    功能简介:

numDocs:当前系统中的文档数量,可能大于推送的文件个数,因为一个推送文件可能包含多个文档(即多个<doc>标签)
maxDoc:可能比numDocs的值要大,因为solr中的一次更新操作也会导致maxDoc增大
deletedDocs:文档的更新也会导致deltedDocs的值也会加1




管理界面 - query菜单

    截图下:


    功能简介:

q输入框:
指定搜索语法,如搜索city字段为上海的文档, 语法为 city:上海


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!