你的位置:首页 > Java教程

[Java教程]solr 学习片段


全文检索技术——Solr

站内搜索技术选型

1、使用Lucene来实现:需要大量的编码才能实现。集群方案需要自己解决。查询速度的优化都需要自己解决。不推荐使用。

2、使用搜素引擎提供的接口实现站内搜索。索引库在搜索引擎上,维护不方便。开发简单。

3、使用Solr来实现站内搜索。可以独立运行,提供全套的解决方案。Solr集群、索引库的优化。推荐使用。

 

什么是solr

3.1 什么是solr

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。

Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 文档,Solr根据文档添加、删除、更新索引 。Solr 搜索只需要发送 HTTP GET 请求,然后对 Solr 返回、json等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。

 

3.2 Solr和lucene的区别

Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索引擎,Lucene提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索引擎。

 Solr的目标是打造一款企业级的搜索引擎系统,它是一个搜索引擎服务,可以独立运行,通过Solr可以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

 

3.3 Solr的下载

下载地址:lucene.apache.org/solr/mirrors-solr-latest-redir.html?

版本是:4.10.3

 

Solr的安装及配置

4.1 Solr的运行环境

Solr4.10要求jdk1.7.0及以上版本

要求tomcat7.0以上

 

4.2 Solr集成tomcat

第一步:安装tomcat,我们使用的版本是apache-tomcat-7.0.53

第二步:部署solr的war包。将solr-4.10.3.war复制到tomcat的webapp下。改名为solr.war

第三步:解压Solr.war,在solr\WEB-INF\lib添加日志需要的jar包。

将solr-4.10.3\example\lib\ext目录下的jar复制到lib下。

第四步:配置solrhome,及solrcore。

        Solrhome也就是solr服务器所有配置文件存放的文件夹。

\solr-4.10.3\example\solr文件夹就是一个标准的solrhome。

1)solr文件夹复制到指定位置E:\B_develop\apache-tomcat-7.0.67\webapps\solr\solrhome

2)Solrcore:collection1就是一个solrcore,一个solrcore就是一个索引库。可以对比mysql的数据库,一个solrcore相当于一个mysql 的数据库。索引库和索引库之间相互独立。

3)collection1\conf:每个sorlcore的配置信息。

4)Solrconfig.:solrcore的配置,如果使用默认配置可以不用修改。

luceneMatchVersion:匹配的lucene的版本

Lib:solrcore扩展包的位置,默认是collection1\lib文件夹,如果没有lib文件夹就创建一个。

dataDir:索引库存放的位置。默认是collection1\data文件夹,如果没有sorl会自动创建。

查询索引使用的URL:

<requestHandler name="/select" >

维护索引使用的url:

<requestHandler name="/update" >

 

默认查询条件:

<defaultQuery>*:*</defaultQuery>

第五步:将solrhome的位置告诉solr服务。使用jndi的方式。修改web.

 

修改solrhome

 

第六步:启动tomcat

第七步:访问solr服务http://localhost:8080/solr

 

4.3 管理界面介绍

4.3.1 添加solrCore

第一步:复制collection1为collection2

第二步:修改core.properties文件将name=collection2

第三步:重启tomcat

 

4.3.2 选择solrcore

在下拉框中选型要查看或者维护的solrcore

 

4.3.3 Analysis

 

4.3.4 Dataimport

可以讲关系型数据库中的数据导入到索引库中。

 

4.3.5 维护索引

 

4.3.6 搜索文档的功能

 

 

Schema.

在schema.定义域及域的类型,必须先定义后使用。

5.1 Field域定义

Name:域的名字

Type:域的类型,可以可以自定义。也是在schema.中定义。

Indexed:是否索引

Stored:是否存储

multiValued:是否多值,就是在一个域中存储多个值,存储一个数组。

5.2 dynamicField动态域

如果一个未定义的域可以和动态域相匹配那么也是可以使用的。

 

Name:动态域的表达式

Type:域的类型

Indexed:是否索引

Stored:是否存储

multiValued:是否多值,就是在一个域中存储多个值,存储一个数组。

5.3 uniqueKey

索引库的主键。

每个文档必须包含id域。

 

5.4 copyField复制域

Source:源域

Dest:目标域

当向索引库中添加文档时,copyfield会自动将源域的内容复制到目标域中。

例如:

<copyField source="cat" dest="text"/>

 

5.5 fieldType域类型

Name:域类型的名称

Class:实际对应的java类型

Analyzer:可以配置第三方分析器。可以自定义数据类型配置中文分析器。

 

 

配置中文分析器

修改schema.先添加fieldType然后再添加field。

 

第一步:先将IKAnalyzer的jar包添加到solr工程中。

第二步:把配置文件复制到solr工程的classpath下。

第三步:修改schema.添加自定义的fieldtype。

  <!-- IKAnalyzer-->

  <fieldType name="text_ik" >

    <analyzer />

   </fieldType>

第四步:在schema.添加自定义的域field。

第五步:重启tomcat

 

6.1 设置业务系统Field

<!--product-->

   <field name="product_name" type="text_ik" indexed="true" stored="true"/>

   <field name="product_price"  type="float" indexed="true" stored="true"/>

   <field name="product_description" type="text_ik" indexed="true" stored="false" />

   <field name="product_picture" type="string" indexed="false" stored="true" />

   <field name="product_catalog_name" type="string" indexed="true" stored="true" />

 

   <field name="product_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>

   <copyField source="product_name" dest="product_keywords"/>

   <copyField source="product_description" dest="product_keywords"/>

和商品表的表结构对应。

 

索引库的维护

7.1 添加文档

{"id":"a0001","title_ik":"中文分析器的title","content_ik":"接下来点击顶部导航的“搜索框样式”,进入搜索框设置界面。"}

7.2 文档的删除

7.2.1 根据id删除文档

 

 

7.2.2 根据查询删除文档

 

7.3 更新文档

先删除后添加。

 

只需要再添加一个id和需要更新的文档id一致新文档就可以了。

 

7.4 批量添加文档,使用dataimport插件

7.4.1 Dataimport插件需要的jar包

 

7.4.2 配置插件

第一步:先将插件依赖的jar包添加到solrcore中。放到Collection1\lib下。

第二步:mysql数据库的驱动也添加到Collection1\lib下

第三步:修改solrconfig.配置文件。

<requestHandler name="/dataimport"

>

    <lst name="defaults">

      <str name="config">data-config.

    </lst>

</requestHandler> 

第四步:创建data-config.文件放到collection\conf文件夹下。

第五步:重启tomcat。

 

先清空索引库然后再倒入。

 

索引库的查询

Request-Handler:/select

Q:查询条件。默认是*:*。完全支持lucene的查询语法,并且范围查询语法支持数值类型的域。

Fq:过滤查询条件。是在查结果基础上,进一步过滤。查询语法和查询条件的语法一致。

Sort:排序。指定排序的域在后面跟上asc|desc 。如果多个排序条件,使用半角逗号“,”分隔。

分页处理:

Start:起始记录的下标。

Row:每页显示的记录数。

Fl:返回结果中文档包含的域列表。多个域使用半角逗号“,”分隔。不设置此属性默认返回全部域。

Df:默认搜索域。如果查询条件中不指定搜索的域,而且不设置默认搜索域,就查询不到结果。

Wt:返回结果的数据格式。可以是json、

Hl:高亮显示

1)hl.fl:高亮显示的域

2)Hl.simple.pre:前缀

3)Hl.simple.post:后缀

使用solrJ客户端

9.1 依赖的jar包

 

 

 

9.2 使用solrJ维护索引

索引的增删改操作。

 

9.2.1 实现步骤

第一步:创建一个java工程

第二步:导入jar包。

第三步:创建和服务端的连接。SolrServer对象,HttpSolrServer创建连接。

第四步:创建一个文档对象。SolrInputDocument。

第五步:向文档对象中添加域。

第六步:把文档对象发送给服务端。

第七步:关闭连接。

 

9.2.2 添加文档

 

代码实现

//添加文档

@Test

public void addDocument() throws Exception {

//建立连接

//参数是solr服务器的地址

SolrServer server = new HttpSolrServer("http://localhost:8080/solr");

//创建文档对象

SolrInputDocument document = new SolrInputDocument();

//添加域,域名必须是schema.

document.addField("id", "a001");

document.addField("title_ik", "新添加的文档");

document.addField("content_ik", "新添加文档的内容");

document.addField("product_name", "还没想好叫什么名字");

//把文档添加到索引库

server.add(document);

//提交修改

server.commit();

 

}

 

9.2.3 删除文档

9.2.3.1 根据id删除文档

//删除文档

@Test

public void deleteDocument() throws Exception {

//建立连接

//参数是solr服务器的地址

SolrServer server = new HttpSolrServer("http://localhost:8080/solr");

//删除指定id的文档

server.deleteById("a001");

//提交

server.commit();

}

 

 

 

9.2.3.2 根据查询删除文档

 

 

9.2.3.3 修改文档

没有专门的修改文档的方法,直接在添加一条新的文档,要求id和需要更新的文档id保持一致就可以了。

跟添加文档的方法一样。

 

9.3 solrJ查询索引库

 

//查询索引库

@Test

public void searchIndex() throws Exception {

//建立连接

SolrServer server = new HttpSolrServer("http://localhost:8080/solr");

//创建一个query对象

SolrQuery query = new SolrQuery();

//查询条件

query.setQuery("花儿");

//过滤条件

query.addFilterQuery("product_price:[10 TO 100]");

//排序

query.setSort("product_price", ORDER.asc);

//分页处理

query.setStart(0);

query.setRows(10);

//文档中包含的域列表

query.setFields("product_picture", "product_catalog_name", "product_price", "product_name", "id");

//设置默认搜索域

query.set("df", "product_keywords");

//高亮设置

query.setHighlight(true);

//高亮显示的域

query.addHighlightField("product_name");

//设置高亮前缀

query.setHighlightSimplePre("<em>");

//高亮后缀

query.setHighlightSimplePost("</em>");

//执行查询

QueryResponse queryResponse = server.query(query);

//取查询结果

SolrDocumentList solrDocumentList = queryResponse.getResults();

//获得查询结果的总数量

System.out.println("查询结果的总数量" + solrDocumentList.getNumFound());

//遍历查询结果

for (SolrDocument solrDocument : solrDocumentList) {

System.out.println(solrDocument.get("id"));

System.out.println(solrDocument.get("product_picture"));

System.out.println(solrDocument.get("product_catalog_name"));

System.out.println(solrDocument.get("product_price"));

//取高亮显示

String name = "";

//取高亮内容

Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();

List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");

if (null == list) {

name = (String) solrDocument.get("product_name");

} else {

name = list.get(0);

}

System.out.println(name);

 

}

}