1. 什么是Slor

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。

Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。


  1. Solr和Lucene的区别
    Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索应用。Lucene仅提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索应用。
     Solr的目标是打造一款企业级的搜索引擎系统,它是基于Lucene一个搜索引擎服务,可以独立运行,通过Solr可以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

  1. Solr的架构图

图片


  1. solr的安装配置

1.访问官网: http://lucene.apache.org/
2.下载solr的工具包

图片

3.解压solr的安装包

图片

  1. 目录说明:
    bin:solr的运行脚本
    contrib:solr的一些扩展jar包,用于增强solr的功能。
    dist:该目录包含build过程中产生的war和jar文件,以及相关的依赖文件。
    docs:solr的API文档
    example:solr工程的例子目录:
    l example/solr:该目录是一个标准的SolrHome,它包含一个默认的SolrCore
    l example/multicore:该目录包含了在Solr的multicore中设置的多个Core目录。
    l example/webapps:该目录中包括一个solr.war,该war可作为solr的运行实例工程。
    l icenses:solr相关的一些许可信息

  2. 搭建运行环境
    solr 需要运行在一个Servlet容器中,Solr4.4.0要求jdk使用1.7以上,Solr默认提供Jetty(java写的Servlet容器),本教程使用Tocmat作为Servlet容器
    相关环境如下:
    l Solr:4.4.0
    l Jdk环境:1.7.0_72
    l Web服务器(servlet容器):Tomcat 7X

图片

6.将solr包中的solr.war包拷贝到tomcat的webapps中

图片

7.解压缩 webapps中solr的war包

图片

8.将solr文件夹中的依赖包引入到webapps中solr的WEB-INF的/lib目录中

图片
图片

9.创建solr的数据存储目录

图片

10.将solr-4.4.0目录中的example目录中solr目录的文件存放到solrhome目录中

图片

11.配置tomcat中webapps目录中的solr应用的web.xml 指定的数据存储目录

图片

12.启动tomcat访问solr服务器

http://localhost:8989/solr


  1. solr后台管理界面

图片

solr 的配置文件说明:
核心配置文件为: 数据目录中每个core目录中的 solrConfig.xxml
域定义配置文件为:数据目录中每个core目录中的sechma.xxml


  1. Schema.xml
  2. field 域
l Name:域的名称 l Type:域的类型 l Indexed:是否索引 l Stored:是否存储 l Required:是否必须 l multiValued:是否是多值,存储多个值时设置为true,solr允许一个Field存储多个值,比如存储一个用户的好友id(多个),商品的图片(多个,大图和小图)
  1. fieldType 域类型
                                                                                                         l name:域类型的名称 l class:指定域类型的solr类型。 l analyzer:指定分词器。在FieldType定义的时候最重要的就是定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤。 l type:index和query。Index 是创建索引,query是查询索引。 l tokenizer:指定分词器 l filter:指定过滤器
  1. dynamicField 动态域
l Name:动态域的名称,是一个表达式,*匹配任意字符,只要域的名称和表达式的规则能够匹配就可以使用。 例如:搜索时查询条件【product_i:钻石】就可以匹配这个动态域,可以直接使用,不用单独再定义一个product_i域。
  1. copyField 复制域
可以将多个Field复制到一个Field中,以便进行统一的检索。当创建索引时,solr服务器会自动的将源域的内容复制到目标域中。 l source:源域 l dest:目标域,搜索时,指定目标域为默认搜索域,可以提供查询效率。
  1. uniqueKey

id
相当于主键,每个文档中必须有一个id域。


  1. Solr配置中文IK分词器

第一步:把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下。
第二步:复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classpath下。
第三步:在schema.xml中添加一个自定义的fieldType,使用中文分析器。


      
    
第四步:定义field,指定field的type属性为text_ik


   
第五步:重启tomcat

图片


  1. 定义业务字段

1.1 需求

思路:

  1. 要使用solr实现电商网站中商品搜索。
  2. 电商中商品信息在mysql数据库中存储了,将mysql数据库中数据在solr中创建索引。
  3. 需要在solr的schema.xml文件定义商品Field。

1.2 **定义步骤 **

先确定定义的商品document的field有哪些?
可以根据mysql数据库中商品表的字段来确定:
products商品表:

图片

分析:

  1. 商品document的field包括:pid、name、catalog、catalog_name、price、description、picture
  2. 先定义Fieldtype:solr本身提供的fieldtype类型够用了不用定义新的了。
  3. 再定义Field:
    pid:商品id主键

    name:商品名称

    catalog:商品分类

    catalog_name:商品分类名称

    price:商品价格

    description:商品描述

    picture:商品图片

汇总如下:






  1. dataimport Handler插件

第一步:Dataimport的jar 从solr-4.4.0\dist目录下拷贝solr-dataimporthandler-4.4.0.jar,复制到以下目录:

图片

第二步:配置solrconfig.xml,添加一个requestHandler
 
   
      data-config.xml
     
 

第三步:创建建一个data-config.xml 在collection1\conf\目录下创建data-config.xml文件

<?xml version="1.0" encoding="UTF-8" ?>                             注意: entity 中 name 属性不是固定,可以随意书写

第四步:定义schema.xml的域

   
   


  1. Solrj的基本使用

1.1 什么是solrj

solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJ的API接口操作Solr服务,如下图:

图片

Solrj和图形界面操作的区别就类似于数据库中你使用jdbc和mysql客户端的区别一样。

1.2 Solrj的使用

第一步:项目引入solrj的相关依赖

org.apache.solr
solr-solrj
4.4.0

commons-logging commons-logging 1.1.3

第二步:操作solr服务器
1.执行增加操作:
@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
//添加文档
SolrInputDocument solrInputDocument = new SolrInputDocument();
solrInputDocument.addField(“id”, UUID.randomUUID().toString());
solrInputDocument.addField(“product_name”, “iphone x”);
solrInputDocument.addField(“product_description”, “苹果 是一个好的机器”);
solrInputDocument.addField(“product_price”, 199);
solrServer.add(solrInputDocument);
solrServer.commit();
}
2.执行删除操作
@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
solrServer.deleteById(“5ea57018-53da-47f8-943f-69168a95a88d”);
solrServer.commit();
}
3.执行更新操作
注意:更新与添加一致,存在id增更新,不存在则添加
4.执行查询操作
@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.set(“q”,":");
QueryResponse query = solrServer.query(solrQuery);
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_description”));
System.out.println(”===================================”);
}
}


  1. solrj的查询

1.1 分页查询

@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.set(“q”,":");
//设置分页
//设置起始条数
solrQuery.set(“start”,0);
//设置每页显示的记录数
solrQuery.set(“rows”,5);
QueryResponse query = solrServer.query(solrQuery);
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_catalog_name”));
System.out.println(”===================================”);
}
}

1.2 查询结果只显示指定字段的值

@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.set(“q”,":");
//查询结果显示指定域的值
solrQuery.set(“fl”,“id,product_name,product_catalog_name”);
QueryResponse query = solrServer.query(solrQuery);
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_catalog_name”));
System.out.println(”===================================”);
}
}

1.3 过滤条件查询

@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.set(“q”,":");
//设置过滤条件
//这种方式相当于or
solrQuery.set(“fq”,“product_catalog_name:‘幽默杂货’”);
solrQuery.set(“fq”,“product_price:[* TO 10]”);
//这种方式 相当于and
solrQuery.setFilterQueries(“product_catalog_name:幽默杂货”,“product_price:[* TO 10]”);
QueryResponse query = solrServer.query(solrQuery);
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_catalog_name”));
System.out.println(”===================================”);
}
}

1.4 默认搜索的域

@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.setQuery(“雕刻”);
//设置默认搜索域
solrQuery.set(“df”,“product_keywords”);
QueryResponse query = solrServer.query(solrQuery);
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_catalog_name”));
System.out.println(”===================================”);
}
}

1.5 设置排序条件

@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.setQuery(“雕刻”);
//设置默认搜索域
solrQuery.set(“df”,“product_keywords”);
//设置排序条件
solrQuery.setSort(“product_price”, SolrQuery.ORDER.asc);
QueryResponse query = solrServer.query(solrQuery);
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_catalog_name”));
System.out.println(”===================================”);
}
}

1.6 高亮查询

@Test
public void test() throws IOException, SolrServerException {
//连接solr服务器
SolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//设置查询条件
solrQuery.setQuery(“雕刻”);
//设置默认搜索域
solrQuery.set(“df”,“product_keywords”);
//开启高亮
solrQuery.setHighlight(true);
//指定高亮的域
solrQuery.addHighlightField(“product_name”);
solrQuery.addHighlightField(“product_description”);
//指定高亮的前缀
solrQuery.setHighlightSimplePre("");
//指定高亮后缀
solrQuery.setHighlightSimplePost("");
QueryResponse query = solrServer.query(solrQuery);
//获取高亮结果
//Map 最外层 中key 是id 值为Map
//Map 内层 中key 是域 值为List
//List 高亮的具体内容
Map<String, Map<String, List>> highlighting = query.getHighlighting();
SolrDocumentList solrDocuments = query.getResults();
long numFound = solrDocuments.getNumFound();
System.out.println(“总条数: “+numFound);
for (SolrDocument solrDocument : solrDocuments) {
System.out.println(solrDocument.get(“id”));
System.out.println(solrDocument.get(“product_name”));
System.out.println(solrDocument.get(“product_price”));
System.out.println(solrDocument.get(“product_catalog_name”));
System.out.println(”=高亮之后==”);
//处理高亮
Map<String, List> listMap = highlighting.get(solrDocument.get(“id”));
if(listMap.containsKey(“product_name”)){
System.out.println(listMap.get(“product_name”).get(0));
}
}
}

1.7 综合查询

@Test
public void testAllQuery() throws SolrServerException {
//创建solrserver客户端对象
HttpSolrServer solrServer = new HttpSolrServer(“http://localhost:8989/solr/collection1”);
SolrQuery solrQuery = new SolrQuery();
//指定默认域 指定查询条件为 雕刻 指定过滤条件 幽默杂货and 价格在0-10 指定排序 price 开启分页 高亮结果展示 响应的结果中只有 id name price
solrQuery.setQuery(“雕刻”)
.setFilterQueries(“product_catalog_name:幽默杂货”,“product_price:[* TO 50]”)//过滤条件
.setSort(“product_price”,SolrQuery.ORDER.asc)//以什么排序
.setHighlight(true)//开启高亮
.setHighlightSimplePre("")//高亮的开始标签
.setHighlightSimplePost("") //高亮的结束标签
.addHighlightField(“product_name”)//高亮字段
.set(“start”,0) //开启条数
.set(“rows”,10000)//每页显示条数
.set(“df”, “product_keywords”) //默认搜索域
.set(“fl”,"*,score");//响应的结果中包含哪些字段
QueryResponse queryResponse = solrServer.query(solrQuery);
//处理高亮
Map<String, Map<String, List>> highlighting = queryResponse.getHighlighting();
SolrDocumentList results = queryResponse.getResults();
System.out.println(“总条数: “+ results.getNumFound());
for (SolrDocument result : results) {
System.out.println(result.get(“id”));
Map<String, List> stringListMap = highlighting.get(result.get(“id”));
if(stringListMap.containsKey(“product_name”)){
System.out.println(stringListMap.get(“product_name”).get(0));
}else{
System.out.println(result.get(“product_name”));
}
System.out.println(result.get(“product_price”));
System.out.println(result.get(“product_picture”));
System.out.println(result.get(“product_catalog_name”));
System.out.println(result.get(“score”));//当前文章的分数
System.out.println(”===============================================”);
}
}


  1. Spring Boot 整合solr开发

第一步: 在pom.xml中引入依赖

org.springframework.boot spring-boot-starter-parent 1.5.7.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-test org.springframework.boot spring-boot-starter-data-solr

第二步:配置springboot的配置文件

server:
port: 8989
context-path: /solr
spring:
data:
solr:
host: http://localhost:8989/solr

第三步:测试solr整合使用
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
public class TestSpringbootSolr {
@Autowired
private SolrClient solrClient;
@Test
public void test() throws IOException, SolrServerException {
SolrQuery params = new SolrQuery();
params.set(“q”,":");
QueryResponse q = solrClient.query(params);
SolrDocumentList results = q.getResults();
System.out.println(“总条数:”+results.getNumFound());
for (SolrDocument result : results) {
System.out.println(result.get(“id”));
System.out.println(result.get(“product_name”));
System.out.println(result.get(“product_price”));
}
}

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐