Solr

solr环境配置

安装solr前,请确保系统中已正确安装jdk8,tomcat8和环境变量的配置。

solr下载及解压

使用命令:

wget http://mirrors.tuna.tsinghua.edu.cn/apache/lucene/solr/7.4.0

从官网下载solr压缩包

解压:

tar -zxvf solr-7.4.0.tgz

配置tomcat启动solr

solr自带jetty启动,这里使用tomcat进行配置启动。

  1. 在tomcat包下的webapps目录新建一个目录,取名solr
  2. 将solr解压包/solr-7.4.0/server/solr-webapp/webapp/下的内容拷贝到刚才tomcat下新建的文件夹solr中
  3. 将/solr-7.4.0/server/lib/ext/下的jar包拷贝到/tomcat/webapps/solr/WEB-INF/lib/下
  4. 将/solr-7.4.0/server/lib/下metrics开头的jar包也拷贝到刚才的目录下
  5. 将/solr-7.4.0/dist/下 solr-dataimporthandler-extras-7.4.0.jar、solr-dataimporthandler-7.4.0.jar也拷贝到刚才的目录下
  6. 在你本地的/home下新建一个文件夹,取名solr-home,将/solr-7.4.0/server/solr下的内容拷贝到刚才新建的solr-home下
  7. 打开并编辑/tomcat/webapps/solr/WEB-INF/web.xml
    内容如下:
<env-entry>
      <env-entry-name>solr/home</env-entry-name>
      <env-entry-value>/home/solr-home</env-entry-value>
      <env-entry-type>java.lang.String</env-entry-type>
</env-entry>

并注释文件末尾的所有 元素节点。

配置solr日志

将/solr-7.4.0/server/resources/下的log4j2.xml文件拷贝到/tomcat/webapps/solr/WEB-INF/classes/下,如果没有则自己创建一个。

创建core

  1. 在/home/solr-home/下创建一个文件夹,文件夹名称为你的core名称,这里设为collection
  2. 将/solr-7.4.0/example/example-DIH/solr/solr下的内容拷贝到刚才创建的collection下,同时在core.properties下添加如下内容:
name=collection

启动tomcat,访问 localhost:8080/solr/index.html 就可以看到solr的界面了。

img

安装IK分词器

1.解压IK分词器的压缩包,进入文件夹

2.将IK分词器的jar包放置到tomcat下solr的WEB_INF下的lib里

3.将IK分词器的conf下的IKAnalyzer.cfg.xml和stopword.dic放置到tomcat下solr的WEB_INF下的classes里(没有classes文件夹务必创建一个)

4.修改/home/solr-home下collection下的managed-schema.xml,添加

<fieldType name="text_ik" class="solr.TextField" positionIncrementGap="100">
    <analyzer type="index">
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false"/>
      <!--  <filter class="org.wltea.analyzer.lucene.IKTokenFilterFactory" useSingle="true" useItself="false" /> -->
    </analyzer>
    <analyzer type="query">
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false"/>
      <!--  <filter class="org.wltea.analyzer.lucene.IKTokenFilterFactory" useSingle="true" useItself="false" /> -->
    </analyzer>
</fieldType>

这其实就是分词器的描述,配置的text_ik就是下图分词器的名字了

使用分词器

重启tomcat,进入对应的index.html,如下图操作在这里插入图片描述

对比两个分词的效果
自带分词

在这里插入图片描述

IK分词器

在这里插入图片描述

Java对Solr索引操作

1.引入Solr对SpringBoot的依赖
dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
2.配置yml
spring:
  data:
    solr:
      #这里的host地址对应配置的solrhome/collection/core.properties中的name的值
      host: http://192.168.9.128:8081/solr/collection
3.引入索引solr客户端
@Autowired
private SolrClient solrClient;
4.Solr索引的新增
public void solrAddOne() throws IOException, SolrServerException {SolrInputDocument solrInputFields = new SolrInputDocument();
    solrInputFields.addField("id",10);
    solrInputFields.addField("goodsName","华为手机是中国手机的领导者,华为");
    solrInputFields.addField("age","22");
    solrInputFields.addField("sex","男");
    //将索引对象保存到索引库中(id相同就是修改)
    solrClient.add(solrInputFields);
    solrClient.commit();
}
5.删除索引
/*删除索引库*/
@Test
public void solrDelete() throws IOException, SolrServerException {
    //根据id删除
    solrClient.deleteById("1");
    //根据能查询到的结果删除(根据商品名为华为的删除)
    //solrClient.deleteByQuery("goodsName:华为");
	solrClient.commit();
}
6.索引修改
//通过新增同样的id,相当于覆盖,但是注意是修改整个索引,包括age属性(被Null覆盖了)
public void solrAddOne() throws IOException, SolrServerException {SolrInputDocument solrInputFields = new SolrInputDocument();
    solrInputFields.addField("id",10);
    solrInputFields.addField("goodsName","华为手机修改过后的值是华为2");
    //将索引对象保存到索引库中(id相同就是修改)
    solrClient.add(solrInputFields);
    solrClient.commit();
}

> QueryResponse类中有几个方法

| 方法名            | 返回值                               | 返回值说明                                         |
| ----------------- | ------------------------------------ | -------------------------------------------------- |
| getResults()      | SolrDocumentList                     | 本身就是一个ArrayList,包含了结果                   |
| getHighlighting() | Map<String,Map<String,List<String>>> | 1:{goodsName=[<font color='red'>华为</font>手机1]} |

result结构图

![1542186163863](C:\Users\user\Documents\1542186163863.png)



```java
@Test
public void query() throws IOException, SolrServerException {
    SolrQuery solrQuery = new SolrQuery();
    //执行查询 id是5的索引
    solrQuery.setQuery("id:5");
    QueryResponse response = solrClient.query(solrQuery);
    SolrDocumentList results = response.getResults();
    for (SolrDocument result : results) {
        String goodsName = (String) result.getFieldValue("goodsName");
        Collection<String> fieldNames = result.getFieldNames();
        System.out.println(goodsName);
        System.out.println("---------------------------------------------");
        for (String fieldName : fieldNames) {
            System.out.print(fieldName);
            System.out.println(result.getFieldValue(fieldName));
        }

    }

}

索引在项目中文字高亮

京东淘宝或者百度都会在搜索时,将关键字进行变色等高亮处理,solr支持对搜索关键字高亮

在这里插入图片描述

方法介绍

Solr查询类SolrQuery中有几个方法,作用如下

方法名作用
setHighlight(boolean b)是否高亮
setHighlightSimplePre(String f)规定高亮文字的样式(前)
setHighlightSimplePost(String f)规定高亮文字的样式(后)
setHighlightSnippets(int num)结果分组:规定查询的文字分成几部分
setHighlightFragsize(int num)规定每部分文字的字数
创建一个关键字查询方法接口
@RequestMapping("/query")
    public String query(String key,Model model) throws IOException, SolrServerException {

        SolrQuery solrQuery = new SolrQuery();
        //设置查询的内容
        if (key.equals("")) {
            solrQuery.setQuery("*:*");
        } else {
         solrQuery.setQuery("goodsName:"+key);
        }
        //设置高亮的格式:前缀后缀
        solrQuery.setHighlight(true);
        solrQuery.setHighlightSimplePre("<font color='red'>");
        solrQuery.setHighlightSimplePost("</font>");
        solrQuery.addHighlightField("goodsName");

        //分成几部分,每部分长度
        solrQuery.setHighlightSnippets(2);
        solrQuery.setHighlightFragsize(5);


        QueryResponse query = solrClient.query(solrQuery);
        SolrDocumentList results = query.getResults();
        Map<String, Map<String, List<String>>> highlighting = query.getHighlighting();
        List<Goods> goodList = new ArrayList<>();
        for (SolrDocument result : results) {
            Goods goods = new Goods();
            Integer id = Integer.parseInt(result.getFieldValue("id")+"");
            if (highlighting.containsKey(id+"")) {
                List<String> goodsNameList = highlighting.get(id + "").get("goodsName");
                StringBuilder sb = new StringBuilder();
                for (String goodsName : goodsNameList) {
                    sb.append(goodsName);
                }
                goods.setGoodsName(sb.toString());
            }
            goods.setAge(Integer.parseInt(result.getFieldValue("age")+""));
            goods.setSex((String) result.getFieldValue("sex"));
            goodList.add(goods);
        }

注意以上setHighlightSnippets()方法中,如果给出的参数>1,即分成多部分内容,那上面goodsNameList集合就不是一个,而是多个,可以通过拼接的方式显示出来.

原本存在的索引
{
    "responseHeader": {
        "status": 0,
        "QTime": 0,
        "params": {
            "q": "*:*"
        }
    },
    "response": {
        "numFound": 10,
        "start": 0,
        "docs": [
            {
                "id": "0",
                "goodsName": "华为手机0",
                "age": "220",
                "_version_": 1617089328451682304
            },
            {
                "id": "2",
                "goodsName": "华为手机2",
                "age": "222",
                "_version_": 1617089328509353984
            },
            {
                "id": "3",
                "goodsName": "华为手机3",
                "age": "223",
                "_version_": 1617089328516694016
            },
            {
                "id": "4",
                "goodsName": "华为手机4",
                "age": "224",
                "_version_": 1617089328524034048
            },
            {
                "id": "5",
                "goodsName": "华为手机5",
                "age": "225",
                "_version_": 1617089328531374080
            },
            {
                "id": "6",
                "goodsName": "华为手机6",
                "age": "226",
                "_version_": 1617089328538714112
            },
            {
                "id": "7",
                "goodsName": "华为手机7",
                "age": "227",
                "_version_": 1617089328546054144
            },
            {
                "id": "8",
                "goodsName": "华为手机8",
                "age": "228",
                "_version_": 1617089328553394176
            },
            {
                "id": "9",
                "goodsName": "华为手机9",
                "age": "229",
                "_version_": 1617089328560734208
            },
            {
                "id": "10",
                "goodsName": "华为手机修改过后的值是华为2",
                "age": "22",
                "_version_": 1617098458274988032
            }
        ]
    }
}
查询的结果是:

在这里插入图片描述

Solr分页

1.新建一个bo类SolrPage
package com.wei.solr.bo;

import java.util.List;

public class SolrPage<T> {

    //初始页
    private Integer page = 1;

    //每页大小
    private Integer pageSize = 10;

    //当前页
    private Integer pageCount;

    //总页数
    private Integer pagSum;

    //数据
    private List<T> datas;

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getPageCount() {
        return pageCount;
    }

    public void setPageCount(Integer pageCount) {
        this.pageCount = pageCount;
    }

    public Integer getPagSum() {
        return pagSum;
    }

    public void setPagSum(Integer pagSum) {
        this.pagSum = pagSum;
    }

    public List<T> getDatas() {
        return datas;
    }

    public void setDatas(List<T> datas) {
        this.datas = datas;
    }
}

2.设置分页参数
方法名设置的作用
setStart从第几条开始
setRows分页取多少条
3.获取开始查询的位置
//从第几条开始
solrQuery.setStart((solrPage.getPage()-1)*solrPage.getPageSize());
//取多少条
solrQuery.setRows(solrPage.getPageSize());
4.获取分页总数
solrClient.query(solrQuery);
SolrDocumentList results = query.getResults();
long numFound = results.getNumFound();
5.获取当前页
solrClient.query(solrQuery);
SolrDocumentList results = query.getResults();
solrPage.setPageCount(solrPage.getPagSum() % solrPage.getPageSize() == 0 ?
                solrPage.getPagSum() / solrPage.getPageSize():
                solrPage.getPagSum() / solrPage.getPageSize()+1);
6.获取数据
solrClient.query(solrQuery);
SolrDocumentList results = query.getResults();
for (SolrDocument result : results) {
    Goods goods = new Goods();
    Integer id = Integer.parseInt(result.getFieldValue("id")+"");
    if (highlighting.containsKey(id+"")) {
        List<String> goodsNameList = highlighting.get(id + "").get("goodsName");
        StringBuilder sb = new StringBuilder();
        for (String goodsName : goodsNameList) {
            sb.append(goodsName+"...");
        }
        goods.setGoodsName(sb.toString());
    }
    goods.setAge(Integer.parseInt(result.getFieldValue("age")+""));
    goods.setSex((String) result.getFieldValue("sex"));
    goodList.add(goods);
    solrPage.setDatas(goodList);
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值